|
26 | 26 | #include "nodes/nodeFuncs.h" |
27 | 27 | #include "optimizer/clauses.h" |
28 | 28 | #include "optimizer/var.h" |
| 29 | +#include "parser/analyze.h" |
29 | 30 | #include "parser/parser.h" |
30 | 31 | #include "storage/lmgr.h" |
31 | 32 | #include "tcop/tcopprot.h" |
32 | 33 | #include "utils/builtins.h" |
33 | 34 | #include "utils/fmgroids.h" |
34 | 35 | #include "utils/hsearch.h" |
35 | 36 | #include "utils/memutils.h" |
| 37 | +#include "utils/ruleutils.h" |
36 | 38 | #include "utils/syscache.h" |
37 | 39 | #include "utils/lsyscache.h" |
38 | 40 | #include "utils/typcache.h" |
@@ -141,7 +143,6 @@ refresh_pathman_relation_info(Oid relid, |
141 | 143 | Datum param_values[Natts_pathman_config_params]; |
142 | 144 | bool param_isnull[Natts_pathman_config_params]; |
143 | 145 | char *expr; |
144 | | - HeapTuple htup; |
145 | 146 | MemoryContext old_mcxt; |
146 | 147 |
|
147 | 148 | AssertTemporaryContext(); |
@@ -193,16 +194,8 @@ refresh_pathman_relation_info(Oid relid, |
193 | 194 |
|
194 | 195 | /* First, fetch type of partitioning expression */ |
195 | 196 | prel->ev_type = exprType(prel->expr); |
196 | | - |
197 | | - htup = SearchSysCache1(TYPEOID, prel->ev_type); |
198 | | - if (HeapTupleIsValid(htup)) |
199 | | - { |
200 | | - Form_pg_type typtup = (Form_pg_type) GETSTRUCT(htup); |
201 | | - prel->ev_typmod = typtup->typtypmod; |
202 | | - prel->ev_collid = typtup->typcollation; |
203 | | - ReleaseSysCache(htup); |
204 | | - } |
205 | | - else elog(ERROR, "cache lookup failed for type %u", prel->ev_type); |
| 197 | + prel->ev_typmod = exprTypmod(prel->expr); |
| 198 | + prel->ev_collid = exprCollation(prel->expr); |
206 | 199 |
|
207 | 200 | /* Fetch HASH & CMP fuctions and other stuff from type cache */ |
208 | 201 | typcache = lookup_type_cache(prel->ev_type, |
@@ -784,6 +777,31 @@ cook_partitioning_expression(const Oid relid, |
784 | 777 | return expr_datum; |
785 | 778 | } |
786 | 779 |
|
| 780 | +/* Canonicalize user's expression (trim whitespaces etc) */ |
| 781 | +char * |
| 782 | +canonicalize_partitioning_expression(const Oid relid, |
| 783 | + const char *expr_cstr) |
| 784 | +{ |
| 785 | + Node *parse_tree; |
| 786 | + Expr *expr; |
| 787 | + char *query_string; |
| 788 | + Query *query; |
| 789 | + |
| 790 | + AssertTemporaryContext(); |
| 791 | + |
| 792 | + /* First we have to build a raw AST */ |
| 793 | + (void) parse_partitioning_expression(relid, expr_cstr, |
| 794 | + &query_string, &parse_tree); |
| 795 | + |
| 796 | + query = parse_analyze(parse_tree, query_string, NULL, 0); |
| 797 | + expr = ((TargetEntry *) linitial(query->targetList))->expr; |
| 798 | + |
| 799 | + /* We don't care about memory efficiency here */ |
| 800 | + return deparse_expression((Node *) expr, |
| 801 | + deparse_context_for(get_rel_name(relid), relid), |
| 802 | + false, false); |
| 803 | +} |
| 804 | + |
787 | 805 | /* Check if query has subqueries */ |
788 | 806 | static bool |
789 | 807 | query_contains_subqueries(Node *node, void *context) |
|
0 commit comments