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

Commit1d8eeb5

Browse files
committed
resolve conflicts caused by a merge of 'rework_query_walkers', add new regression test pathman_rowmarks
2 parentsa98a052 +66c10c8 commit1d8eeb5

File tree

4 files changed

+295
-51
lines changed

4 files changed

+295
-51
lines changed

‎Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ REGRESS = pathman_basic \
1616
pathman_runtime_nodes\
1717
pathman_callbacks\
1818
pathman_domains\
19-
pathman_foreign_keys
19+
pathman_foreign_keys\
20+
pathman_rowmarks
2021
EXTRA_REGRESS_OPTS=--temp-config=$(top_srcdir)/$(subdir)/conf.add
2122
EXTRA_CLEAN =$(EXTENSION)--$(EXTVERSION).sql ./isolation_output
2223

‎expected/pathman_rowmarks.out

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
CREATE EXTENSION pg_pathman;
2+
CREATE SCHEMA rowmarks;
3+
CREATE TABLE rowmarks.first(id int NOT NULL);
4+
CREATE TABLE rowmarks.second(id int NOT NULL);
5+
INSERT INTO rowmarks.first SELECT generate_series(1, 10);
6+
INSERT INTO rowmarks.second SELECT generate_series(1, 10);
7+
SELECT create_hash_partitions('rowmarks.first', 'id', 5);
8+
create_hash_partitions
9+
------------------------
10+
5
11+
(1 row)
12+
13+
/* Not partitioned */
14+
SELECT * FROM rowmarks.second ORDER BY id FOR UPDATE;
15+
id
16+
----
17+
1
18+
2
19+
3
20+
4
21+
5
22+
6
23+
7
24+
8
25+
9
26+
10
27+
(10 rows)
28+
29+
/* Simple case (plan) */
30+
EXPLAIN (COSTS OFF)
31+
SELECT * FROM rowmarks.first ORDER BY id FOR UPDATE;
32+
QUERY PLAN
33+
---------------------------------------
34+
LockRows
35+
-> Sort
36+
Sort Key: first_0.id
37+
-> Append
38+
-> Seq Scan on first_0
39+
-> Seq Scan on first_1
40+
-> Seq Scan on first_2
41+
-> Seq Scan on first_3
42+
-> Seq Scan on first_4
43+
(9 rows)
44+
45+
/* Simple case (execution) */
46+
SELECT * FROM rowmarks.first ORDER BY id FOR UPDATE;
47+
id
48+
----
49+
1
50+
2
51+
3
52+
4
53+
5
54+
6
55+
7
56+
8
57+
9
58+
10
59+
(10 rows)
60+
61+
SELECT FROM rowmarks.first ORDER BY id FOR UPDATE;
62+
--
63+
(10 rows)
64+
65+
SELECT tableoid > 0 FROM rowmarks.first ORDER BY id FOR UPDATE;
66+
?column?
67+
----------
68+
t
69+
t
70+
t
71+
t
72+
t
73+
t
74+
t
75+
t
76+
t
77+
t
78+
(10 rows)
79+
80+
/* A little harder (plan) */
81+
EXPLAIN (COSTS OFF)
82+
SELECT * FROM rowmarks.first
83+
WHERE id = (SELECT id FROM rowmarks.first
84+
ORDER BY id
85+
OFFSET 10 LIMIT 1
86+
FOR UPDATE)
87+
FOR SHARE;
88+
QUERY PLAN
89+
-----------------------------------------------------
90+
LockRows
91+
InitPlan 1 (returns $1)
92+
-> Limit
93+
-> LockRows
94+
-> Sort
95+
Sort Key: first_0.id
96+
-> Append
97+
-> Seq Scan on first_0
98+
-> Seq Scan on first_1
99+
-> Seq Scan on first_2
100+
-> Seq Scan on first_3
101+
-> Seq Scan on first_4
102+
-> Custom Scan (RuntimeAppend)
103+
-> Seq Scan on first_0 first
104+
Filter: (id = $1)
105+
-> Seq Scan on first_1 first
106+
Filter: (id = $1)
107+
-> Seq Scan on first_2 first
108+
Filter: (id = $1)
109+
-> Seq Scan on first_3 first
110+
Filter: (id = $1)
111+
-> Seq Scan on first_4 first
112+
Filter: (id = $1)
113+
(23 rows)
114+
115+
/* A little harder (execution) */
116+
SELECT * FROM rowmarks.first
117+
WHERE id = (SELECT id FROM rowmarks.first
118+
ORDER BY id
119+
OFFSET 5 LIMIT 1
120+
FOR UPDATE)
121+
FOR SHARE;
122+
id
123+
----
124+
6
125+
(1 row)
126+
127+
/* Two tables (plan) */
128+
EXPLAIN (COSTS OFF)
129+
SELECT * FROM rowmarks.first
130+
WHERE id = (SELECT id FROM rowmarks.second
131+
ORDER BY id
132+
OFFSET 5 LIMIT 1
133+
FOR UPDATE)
134+
FOR SHARE;
135+
QUERY PLAN
136+
----------------------------------------------
137+
LockRows
138+
InitPlan 1 (returns $1)
139+
-> Limit
140+
-> LockRows
141+
-> Sort
142+
Sort Key: second.id
143+
-> Seq Scan on second
144+
-> Custom Scan (RuntimeAppend)
145+
-> Seq Scan on first_0 first
146+
Filter: (id = $1)
147+
-> Seq Scan on first_1 first
148+
Filter: (id = $1)
149+
-> Seq Scan on first_2 first
150+
Filter: (id = $1)
151+
-> Seq Scan on first_3 first
152+
Filter: (id = $1)
153+
-> Seq Scan on first_4 first
154+
Filter: (id = $1)
155+
(18 rows)
156+
157+
/* Two tables (execution) */
158+
SELECT * FROM rowmarks.first
159+
WHERE id = (SELECT id FROM rowmarks.second
160+
ORDER BY id
161+
OFFSET 5 LIMIT 1
162+
FOR UPDATE)
163+
FOR SHARE;
164+
id
165+
----
166+
6
167+
(1 row)
168+
169+
DROP SCHEMA rowmarks CASCADE;
170+
NOTICE: drop cascades to 7 other objects
171+
DETAIL: drop cascades to table rowmarks.first
172+
drop cascades to table rowmarks.second
173+
drop cascades to table rowmarks.first_0
174+
drop cascades to table rowmarks.first_1
175+
drop cascades to table rowmarks.first_2
176+
drop cascades to table rowmarks.first_3
177+
drop cascades to table rowmarks.first_4
178+
DROP EXTENSION pg_pathman;

‎sql/pathman_rowmarks.sql

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
CREATE EXTENSION pg_pathman;
2+
CREATESCHEMArowmarks;
3+
4+
5+
CREATETABLErowmarks.first(idintNOT NULL);
6+
CREATETABLErowmarks.second(idintNOT NULL);
7+
8+
INSERT INTOrowmarks.firstSELECT generate_series(1,10);
9+
INSERT INTOrowmarks.secondSELECT generate_series(1,10);
10+
11+
12+
SELECT create_hash_partitions('rowmarks.first','id',5);
13+
14+
/* Not partitioned*/
15+
SELECT*FROMrowmarks.secondORDER BY id FORUPDATE;
16+
17+
/* Simple case (plan)*/
18+
EXPLAIN (COSTS OFF)
19+
SELECT*FROMrowmarks.firstORDER BY id FORUPDATE;
20+
21+
/* Simple case (execution)*/
22+
SELECT*FROMrowmarks.firstORDER BY id FORUPDATE;
23+
SELECTFROMrowmarks.firstORDER BY id FORUPDATE;
24+
SELECT tableoid>0FROMrowmarks.firstORDER BY id FORUPDATE;
25+
26+
/* A little harder (plan)*/
27+
EXPLAIN (COSTS OFF)
28+
SELECT*FROMrowmarks.first
29+
WHERE id= (SELECT idFROMrowmarks.first
30+
ORDER BY id
31+
OFFSET10LIMIT1
32+
FORUPDATE)
33+
FOR SHARE;
34+
35+
/* A little harder (execution)*/
36+
SELECT*FROMrowmarks.first
37+
WHERE id= (SELECT idFROMrowmarks.first
38+
ORDER BY id
39+
OFFSET5LIMIT1
40+
FORUPDATE)
41+
FOR SHARE;
42+
43+
/* Two tables (plan)*/
44+
EXPLAIN (COSTS OFF)
45+
SELECT*FROMrowmarks.first
46+
WHERE id= (SELECT idFROMrowmarks.second
47+
ORDER BY id
48+
OFFSET5LIMIT1
49+
FORUPDATE)
50+
FOR SHARE;
51+
52+
/* Two tables (execution)*/
53+
SELECT*FROMrowmarks.first
54+
WHERE id= (SELECT idFROMrowmarks.second
55+
ORDER BY id
56+
OFFSET5LIMIT1
57+
FORUPDATE)
58+
FOR SHARE;
59+
60+
61+
DROPSCHEMA rowmarks CASCADE;
62+
DROP EXTENSION pg_pathman;

‎src/utils.c

Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static void change_varnos_in_restrinct_info(RestrictInfo *rinfo,
4040
staticboolchange_varno_walker(Node*node,change_varno_context*context);
4141
staticList*get_tableoids_list(List*tlist);
4242
staticvoidlock_rows_visitor(Plan*plan,void*context);
43+
staticboolrowmark_add_tableoids_walker(Node*node,void*context);
4344

4445

4546
/*
@@ -451,6 +452,57 @@ plan_tree_walker(Plan *plan,
451452
visitor(plan,context);
452453
}
453454

455+
staticbool
456+
rowmark_add_tableoids_walker(Node*node,void*context)
457+
{
458+
if (node==NULL)
459+
return false;
460+
461+
if (IsA(node,Query))
462+
{
463+
Query*parse= (Query*)node;
464+
ListCell*lc;
465+
466+
/* Generate 'tableoid' for partitioned table rowmark */
467+
foreach (lc,parse->rowMarks)
468+
{
469+
RowMarkClause*rc= (RowMarkClause*)lfirst(lc);
470+
Oidparent=getrelid(rc->rti,parse->rtable);
471+
Var*var;
472+
TargetEntry*tle;
473+
charresname[64];
474+
475+
/* Check that table is partitioned */
476+
if (!get_pathman_relation_info(parent))
477+
continue;
478+
479+
var=makeVar(rc->rti,
480+
TableOidAttributeNumber,
481+
OIDOID,
482+
-1,
483+
InvalidOid,
484+
0);
485+
486+
/* Use parent's Oid as TABLEOID_STR's key (%u) */
487+
snprintf(resname,sizeof(resname),TABLEOID_STR("%u"),parent);
488+
489+
tle=makeTargetEntry((Expr*)var,
490+
list_length(parse->targetList)+1,
491+
pstrdup(resname),
492+
true);
493+
494+
/* There's no problem here since new attribute is junk */
495+
parse->targetList=lappend(parse->targetList,tle);
496+
}
497+
498+
returnquery_tree_walker((Query*)node,
499+
rowmark_add_tableoids_walker,
500+
NULL,0);
501+
}
502+
503+
returnexpression_tree_walker(node,rowmark_add_tableoids_walker,NULL);
504+
}
505+
454506
/*
455507
* Add missing 'TABLEOID_STR%u' junk attributes for inherited partitions
456508
*
@@ -463,56 +515,7 @@ plan_tree_walker(Plan *plan,
463515
void
464516
rowmark_add_tableoids(Query*parse)
465517
{
466-
ListCell*lc;
467-
468-
check_stack_depth();
469-
470-
foreach(lc,parse->rtable)
471-
{
472-
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lc);
473-
474-
switch(rte->rtekind)
475-
{
476-
caseRTE_SUBQUERY:
477-
rowmark_add_tableoids(rte->subquery);
478-
break;
479-
480-
default:
481-
break;
482-
}
483-
}
484-
485-
/* Generate 'tableoid' for partitioned table rowmark */
486-
foreach (lc,parse->rowMarks)
487-
{
488-
RowMarkClause*rc= (RowMarkClause*)lfirst(lc);
489-
Oidparent=getrelid(rc->rti,parse->rtable);
490-
Var*var;
491-
TargetEntry*tle;
492-
charresname[64];
493-
494-
/* Check that table is partitioned */
495-
if (!get_pathman_relation_info(parent))
496-
continue;
497-
498-
var=makeVar(rc->rti,
499-
TableOidAttributeNumber,
500-
OIDOID,
501-
-1,
502-
InvalidOid,
503-
0);
504-
505-
/* Use parent's Oid as TABLEOID_STR's key (%u) */
506-
snprintf(resname,sizeof(resname),TABLEOID_STR("%u"),parent);
507-
508-
tle=makeTargetEntry((Expr*)var,
509-
list_length(parse->targetList)+1,
510-
pstrdup(resname),
511-
true);
512-
513-
/* There's no problem here since new attribute is junk */
514-
parse->targetList=lappend(parse->targetList,tle);
515-
}
518+
rowmark_add_tableoids_walker((Node*)parse,NULL);
516519
}
517520

518521
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp