Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit8fa83bf

Browse files
committed
introduce function canonicalize_partitioning_expression(), fix typmod & collid in refresh_pathman_relation_info()
1 parent02ff474 commit8fa83bf

File tree

5 files changed

+155
-15
lines changed

5 files changed

+155
-15
lines changed

‎expected/pathman_expressions.out‎

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,99 @@
22
SET search_path = 'public';
33
CREATE EXTENSION pg_pathman;
44
CREATE SCHEMA test_exprs;
5+
/*
6+
* Test partitioning expression canonicalization process
7+
*/
8+
CREATE TABLE test_exprs.canon(c JSONB NOT NULL);
9+
SELECT create_range_partitions('test_exprs.canon', '(C->>''key'')::int8', 1, 10, 2);
10+
create_range_partitions
11+
-------------------------
12+
2
13+
(1 row)
14+
15+
SELECT expr FROM pathman_config; /* check expression */
16+
expr
17+
-------------------------------
18+
((c ->> 'key'::text))::bigint
19+
(1 row)
20+
21+
INSERT INTO test_exprs.canon VALUES ('{ "key": 2, "value": 0 }');
22+
SELECT *, tableoid::REGCLASS FROM test_exprs.canon;
23+
c | tableoid
24+
------------------------+--------------------
25+
{"key": 2, "value": 0} | test_exprs.canon_1
26+
(1 row)
27+
28+
DROP TABLE test_exprs.canon CASCADE;
29+
NOTICE: drop cascades to 3 other objects
30+
CREATE TABLE test_exprs.canon(val TEXT NOT NULL);
31+
CREATE SEQUENCE test_exprs.canon_seq;
32+
SELECT add_to_pathman_config('test_exprs.canon', 'VAL collate "C"', NULL);
33+
add_to_pathman_config
34+
-----------------------
35+
t
36+
(1 row)
37+
38+
SELECT add_range_partition('test_exprs.canon', 'a'::TEXT, 'b');
39+
add_range_partition
40+
---------------------
41+
test_exprs.canon_1
42+
(1 row)
43+
44+
SELECT add_range_partition('test_exprs.canon', 'b'::TEXT, 'c');
45+
add_range_partition
46+
---------------------
47+
test_exprs.canon_2
48+
(1 row)
49+
50+
SELECT add_range_partition('test_exprs.canon', 'c'::TEXT, 'd');
51+
add_range_partition
52+
---------------------
53+
test_exprs.canon_3
54+
(1 row)
55+
56+
SELECT add_range_partition('test_exprs.canon', 'd'::TEXT, 'e');
57+
add_range_partition
58+
---------------------
59+
test_exprs.canon_4
60+
(1 row)
61+
62+
SELECT expr FROM pathman_config; /* check expression */
63+
expr
64+
-------------------
65+
(val COLLATE "C")
66+
(1 row)
67+
68+
INSERT INTO test_exprs.canon VALUES ('b');
69+
SELECT *, tableoid::REGCLASS FROM test_exprs.canon;
70+
val | tableoid
71+
-----+--------------------
72+
b | test_exprs.canon_2
73+
(1 row)
74+
75+
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.canon WHERE val COLLATE "C" < ALL (array['b', 'c']);
76+
QUERY PLAN
77+
---------------------------
78+
Append
79+
-> Seq Scan on canon_1
80+
(2 rows)
81+
82+
EXPLAIN (COSTS OFF) SELECT * FROM test_exprs.canon WHERE val COLLATE "POSIX" < ALL (array['b', 'c']);
83+
QUERY PLAN
84+
-----------------------------------------------------------
85+
Append
86+
-> Seq Scan on canon_1
87+
Filter: ((val)::text < 'b'::text COLLATE "POSIX")
88+
-> Seq Scan on canon_2
89+
Filter: ((val)::text < 'b'::text COLLATE "POSIX")
90+
-> Seq Scan on canon_3
91+
Filter: ((val)::text < 'b'::text COLLATE "POSIX")
92+
-> Seq Scan on canon_4
93+
Filter: ((val)::text < 'b'::text COLLATE "POSIX")
94+
(9 rows)
95+
96+
DROP TABLE test_exprs.canon CASCADE;
97+
NOTICE: drop cascades to 5 other objects
598
/* We use this rel to check 'pathman_hooks_enabled' */
699
CREATE TABLE test_exprs.canary(val INT4 NOT NULL);
7100
CREATE TABLE test_exprs.canary_copy (LIKE test_exprs.canary);

‎sql/pathman_expressions.sql‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,35 @@ CREATE EXTENSION pg_pathman;
55
CREATESCHEMAtest_exprs;
66

77

8+
9+
/*
10+
* Test partitioning expression canonicalization process
11+
*/
12+
13+
CREATETABLEtest_exprs.canon(c JSONBNOT NULL);
14+
SELECT create_range_partitions('test_exprs.canon','(C->>''key'')::int8',1,10,2);
15+
SELECT exprFROM pathman_config;/* check expression*/
16+
INSERT INTOtest_exprs.canonVALUES ('{ "key": 2, "value": 0 }');
17+
SELECT*, tableoid::REGCLASSFROMtest_exprs.canon;
18+
DROPTABLEtest_exprs.canon CASCADE;
19+
20+
21+
CREATETABLEtest_exprs.canon(valTEXTNOT NULL);
22+
CREATESEQUENCEtest_exprs.canon_seq;
23+
SELECT add_to_pathman_config('test_exprs.canon','VAL collate "C"',NULL);
24+
SELECT add_range_partition('test_exprs.canon','a'::TEXT,'b');
25+
SELECT add_range_partition('test_exprs.canon','b'::TEXT,'c');
26+
SELECT add_range_partition('test_exprs.canon','c'::TEXT,'d');
27+
SELECT add_range_partition('test_exprs.canon','d'::TEXT,'e');
28+
SELECT exprFROM pathman_config;/* check expression*/
29+
INSERT INTOtest_exprs.canonVALUES ('b');
30+
SELECT*, tableoid::REGCLASSFROMtest_exprs.canon;
31+
EXPLAIN (COSTS OFF)SELECT*FROMtest_exprs.canonWHERE val COLLATE"C"< ALL (array['b','c']);
32+
EXPLAIN (COSTS OFF)SELECT*FROMtest_exprs.canonWHERE val COLLATE"POSIX"< ALL (array['b','c']);
33+
DROPTABLEtest_exprs.canon CASCADE;
34+
35+
36+
837
/* We use this rel to check 'pathman_hooks_enabled'*/
938
CREATETABLEtest_exprs.canary(val INT4NOT NULL);
1039
CREATETABLEtest_exprs.canary_copy (LIKEtest_exprs.canary);

‎src/include/relation_info.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,9 @@ Datum cook_partitioning_expression(const Oid relid,
292292
constchar*expr_cstr,
293293
Oid*expr_type);
294294

295+
char*canonicalize_partitioning_expression(constOidrelid,
296+
constchar*expr_cstr);
297+
295298
/* Global invalidation routines */
296299
voiddelay_pathman_shutdown(void);
297300
voiddelay_invalidation_parent_rel(Oidparent);

‎src/pl_funcs.c‎

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include"nodes/nodeFuncs.h"
3535
#include"utils/builtins.h"
3636
#include"utils/inval.h"
37-
#include"utils/ruleutils.h"
3837
#include"utils/snapmgr.h"
3938
#include"utils/lsyscache.h"
4039
#include"utils/syscache.h"
@@ -832,9 +831,7 @@ add_to_pathman_config(PG_FUNCTION_ARGS)
832831
expr_datum=cook_partitioning_expression(relid,expression,&expr_type);
833832

834833
/* Canonicalize user's expression (trim whitespaces etc) */
835-
expression=deparse_expression(stringToNode(TextDatumGetCString(expr_datum)),
836-
deparse_context_for(get_rel_name(relid),relid),
837-
false, false);
834+
expression=canonicalize_partitioning_expression(relid,expression);
838835

839836
/* Check hash function for HASH partitioning */
840837
if (parttype==PT_HASH)

‎src/relation_info.c‎

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
#include"nodes/nodeFuncs.h"
2727
#include"optimizer/clauses.h"
2828
#include"optimizer/var.h"
29+
#include"parser/analyze.h"
2930
#include"parser/parser.h"
3031
#include"storage/lmgr.h"
3132
#include"tcop/tcopprot.h"
3233
#include"utils/builtins.h"
3334
#include"utils/fmgroids.h"
3435
#include"utils/hsearch.h"
3536
#include"utils/memutils.h"
37+
#include"utils/ruleutils.h"
3638
#include"utils/syscache.h"
3739
#include"utils/lsyscache.h"
3840
#include"utils/typcache.h"
@@ -141,7 +143,6 @@ refresh_pathman_relation_info(Oid relid,
141143
Datumparam_values[Natts_pathman_config_params];
142144
boolparam_isnull[Natts_pathman_config_params];
143145
char*expr;
144-
HeapTuplehtup;
145146
MemoryContextold_mcxt;
146147

147148
AssertTemporaryContext();
@@ -193,16 +194,8 @@ refresh_pathman_relation_info(Oid relid,
193194

194195
/* First, fetch type of partitioning expression */
195196
prel->ev_type=exprType(prel->expr);
196-
197-
htup=SearchSysCache1(TYPEOID,prel->ev_type);
198-
if (HeapTupleIsValid(htup))
199-
{
200-
Form_pg_typetyptup= (Form_pg_type)GETSTRUCT(htup);
201-
prel->ev_typmod=typtup->typtypmod;
202-
prel->ev_collid=typtup->typcollation;
203-
ReleaseSysCache(htup);
204-
}
205-
elseelog(ERROR,"cache lookup failed for type %u",prel->ev_type);
197+
prel->ev_typmod=exprTypmod(prel->expr);
198+
prel->ev_collid=exprCollation(prel->expr);
206199

207200
/* Fetch HASH & CMP fuctions and other stuff from type cache */
208201
typcache=lookup_type_cache(prel->ev_type,
@@ -784,6 +777,31 @@ cook_partitioning_expression(const Oid relid,
784777
returnexpr_datum;
785778
}
786779

780+
/* Canonicalize user's expression (trim whitespaces etc) */
781+
char*
782+
canonicalize_partitioning_expression(constOidrelid,
783+
constchar*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+
returndeparse_expression((Node*)expr,
801+
deparse_context_for(get_rel_name(relid),relid),
802+
false, false);
803+
}
804+
787805
/* Check if query has subqueries */
788806
staticbool
789807
query_contains_subqueries(Node*node,void*context)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp