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

Commite8521d3

Browse files
committed
Add support for CREATE TABLE .. PARTITION OF
1 parent48df7a3 commite8521d3

File tree

5 files changed

+164
-24
lines changed

5 files changed

+164
-24
lines changed

‎expected/pathman_declarative.out

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ CREATE TABLE test.range_rel (
77
idSERIAL PRIMARY KEY,
88
dtDATE NOT NULL
99
);
10+
CREATE TABLE test.r2 (LIKE test.range_rel);
11+
ALTER TABLE test.range_rel ATTACH PARTITION test.r2
12+
FOR VALUES FROM ('2015-05-01') TO ('2015-06-01');
13+
ERROR: "range_rel" is not partitioned
1014
INSERT INTO test.range_rel (dt)
1115
SELECT g FROM generate_series('2015-01-01', '2015-04-30', '1 day'::interval) AS g;
1216
SELECT pathman.create_range_partitions('test.range_rel', 'dt',
@@ -25,7 +29,12 @@ SELECT * FROM pathman.pathman_partition_list;
2529
test.range_rel | test.range_rel_4 | 2 | dt | 04-01-2015 | 05-01-2015
2630
(4 rows)
2731

28-
CREATE TABLE test.r2 (LIKE test.range_rel);
32+
ALTER TABLE test.range_rel ATTACH PARTITION test.r2
33+
FOR VALUES IN ('2015-05-01', '2015-06-01');
34+
ERROR: pg_pathman only supports queries for range partitions
35+
ALTER TABLE test.range_rel ATTACH PARTITION test.r2
36+
FOR VALUES FROM ('2014-05-01') TO ('2015-06-01');
37+
ERROR: specified range [05-01-2014, 06-01-2015) overlaps with existing partitions
2938
ALTER TABLE test.range_rel ATTACH PARTITION test.r2
3039
FOR VALUES FROM ('2015-05-01') TO ('2015-06-01');
3140
SELECT * FROM pathman.pathman_partition_list;
@@ -66,7 +75,27 @@ SELECT * FROM pathman.pathman_partition_list;
6675
id | integer | | not null | | plain | |
6776
dt | date | | not null | | plain | |
6877

78+
CREATE TABLE test.r4 PARTITION OF test.range_rel
79+
FOR VALUES IN ('2015-05-01', '2015-06-01');
80+
ERROR: pg_pathman only supports queries for range partitions
81+
CREATE TABLE test.r4 PARTITION OF test.range_rel
82+
FOR VALUES FROM ('2014-05-01') TO ('2015-06-01');
83+
ERROR: specified range [05-01-2014, 06-01-2015) overlaps with existing partitions
84+
CREATE TABLE test.r4 PARTITION OF test.range_rel
85+
FOR VALUES FROM ('2015-06-01') TO ('2016-01-01');
86+
\d+ test.r4;
87+
Table "test.r4"
88+
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
89+
--------+---------+-----------+----------+--------------------------------------------+---------+--------------+-------------
90+
id | integer | | not null | nextval('test.range_rel_id_seq'::regclass) | plain | |
91+
dt | date | | not null | | plain | |
92+
Indexes:
93+
"r4_pkey" PRIMARY KEY, btree (id)
94+
Check constraints:
95+
"pathman_r4_check" CHECK (dt >= '06-01-2015'::date AND dt < '01-01-2016'::date)
96+
Inherits: test.range_rel
97+
6998
DROP SCHEMA test CASCADE;
70-
NOTICE: drop cascades to7 other objects
99+
NOTICE: drop cascades to8 other objects
71100
DROP EXTENSION pg_pathman CASCADE;
72101
DROP SCHEMA pathman CASCADE;

‎sql/pathman_declarative.sql

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,20 @@ CREATE TABLE test.range_rel (
99
idSERIALPRIMARY KEY,
1010
dtDATENOT NULL
1111
);
12+
CREATETABLEtest.r2 (LIKEtest.range_rel);
13+
ALTERTABLEtest.range_rel ATTACH PARTITIONtest.r2
14+
FORVALUESFROM ('2015-05-01') TO ('2015-06-01');
1215

1316
INSERT INTOtest.range_rel (dt)
1417
SELECT gFROM generate_series('2015-01-01','2015-04-30','1 day'::interval)AS g;
1518
SELECTpathman.create_range_partitions('test.range_rel','dt',
1619
'2015-01-01'::DATE,'1 month'::INTERVAL);
1720

1821
SELECT*FROMpathman.pathman_partition_list;
19-
CREATETABLEtest.r2 (LIKEtest.range_rel);
22+
ALTERTABLEtest.range_rel ATTACH PARTITIONtest.r2
23+
FORVALUESIN ('2015-05-01','2015-06-01');
24+
ALTERTABLEtest.range_rel ATTACH PARTITIONtest.r2
25+
FORVALUESFROM ('2014-05-01') TO ('2015-06-01');
2026
ALTERTABLEtest.range_rel ATTACH PARTITIONtest.r2
2127
FORVALUESFROM ('2015-05-01') TO ('2015-06-01');
2228
SELECT*FROMpathman.pathman_partition_list;
@@ -25,6 +31,14 @@ ALTER TABLE test.range_rel DETACH PARTITION test.r2;
2531
SELECT*FROMpathman.pathman_partition_list;
2632
\d+test.r2;
2733

34+
CREATETABLEtest.r4 PARTITION OFtest.range_rel
35+
FORVALUESIN ('2015-05-01','2015-06-01');
36+
CREATETABLEtest.r4 PARTITION OFtest.range_rel
37+
FORVALUESFROM ('2014-05-01') TO ('2015-06-01');
38+
CREATETABLEtest.r4 PARTITION OFtest.range_rel
39+
FORVALUESFROM ('2015-06-01') TO ('2016-01-01');
40+
\d+test.r4;
41+
2842
DROPSCHEMA test CASCADE;
2943
DROP EXTENSION pg_pathman CASCADE;
3044
DROPSCHEMA pathman CASCADE;

‎src/declarative.c

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include"declarative.h"
22
#include"utils.h"
3+
#include"partition_creation.h"
34

45
#include"fmgr.h"
56
#include"access/htup_details.h"
@@ -57,31 +58,37 @@ modify_declative_partitioning_query(Query *query)
5758
}
5859

5960
/* is it one of declarative partitioning commands? */
60-
boolis_pathman_related_partitioning_cmd(Node*parsetree)
61+
bool
62+
is_pathman_related_partitioning_cmd(Node*parsetree,Oid*parent_relid)
6163
{
6264
if (IsA(parsetree,AlterTableStmt))
6365
{
6466
ListCell*lc;
6567
AlterTableStmt*stmt= (AlterTableStmt*)parsetree;
6668
intcnt=0;
6769

70+
*parent_relid=RangeVarGetRelid(stmt->relation,NoLock, false);
71+
if (get_pathman_relation_info(*parent_relid)==NULL)
72+
return false;
73+
74+
/*
75+
* Since cmds can contain multiple commmands but we can handle only
76+
* two of them here, so we need to check that there are only commands
77+
* we can handle. In case if cmds contain other commands we skip all
78+
* commands in this statement.
79+
*/
6880
foreach(lc,stmt->cmds)
6981
{
7082
AlterTableCmd*cmd= (AlterTableCmd*)lfirst(lc);
71-
intsubtype=cmd->subtype;
72-
73-
if (subtype<0)
74-
subtype=-subtype;
75-
76-
switch (subtype)
83+
switch (abs(cmd->subtype))
7784
{
7885
caseAT_AttachPartition:
7986
caseAT_DetachPartition:
8087
/*
81-
*we need to fix all subtypes,
88+
*We need to fix all subtypes,
8289
* possibly we're not going to handle this
8390
*/
84-
cmd->subtype=-(cmd->subtype);
91+
cmd->subtype=abs(cmd->subtype);
8592
continue;
8693
default:
8794
cnt++;
@@ -90,6 +97,26 @@ bool is_pathman_related_partitioning_cmd(Node *parsetree)
9097

9198
return (cnt==0);
9299
}
100+
elseif (IsA(parsetree,CreateStmt))
101+
{
102+
/* inhRelations != NULL, partbound != NULL, tableElts == NULL */
103+
CreateStmt*stmt= (CreateStmt*)parsetree;
104+
105+
if (stmt->inhRelations&&stmt->partbound!=NULL)
106+
{
107+
RangeVar*rv=castNode(RangeVar,linitial(stmt->inhRelations));
108+
*parent_relid=RangeVarGetRelid(rv,NoLock, false);
109+
if (get_pathman_relation_info(*parent_relid)==NULL)
110+
return false;
111+
112+
if (stmt->tableElts!=NIL)
113+
elog(ERROR,"pg_pathman doesn't support column definitions "
114+
"in declarative syntax yet");
115+
116+
return true;
117+
118+
}
119+
}
93120
return false;
94121
}
95122

@@ -157,10 +184,10 @@ transform_bound_value(ParseState *pstate, A_Const *con,
157184
}
158185

159186
/* handle ALTER TABLE .. ATTACH PARTITION command */
160-
voidhandle_attach_partition(AlterTableStmt*stmt,AlterTableCmd*cmd)
187+
void
188+
handle_attach_partition(Oidparent_relid,AlterTableCmd*cmd)
161189
{
162-
Oidparent_relid,
163-
partition_relid,
190+
Oidpartition_relid,
164191
proc_args[]= {REGCLASSOID,REGCLASSOID,
165192
ANYELEMENTOID,ANYELEMENTOID };
166193

@@ -181,7 +208,10 @@ void handle_attach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
181208

182209
Assert(cmd->subtype==AT_AttachPartition);
183210

184-
parent_relid=RangeVarGetRelid(stmt->relation,NoLock, false);
211+
if (pcmd->bound->strategy!=PARTITION_STRATEGY_RANGE)
212+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
213+
errmsg("pg_pathman only supports queries for range partitions")));
214+
185215
if ((prel=get_pathman_relation_info(parent_relid))==NULL)
186216
elog(ERROR,"relation is not partitioned");
187217

@@ -231,7 +261,8 @@ void handle_attach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
231261
}
232262

233263
/* handle ALTER TABLE .. DETACH PARTITION command */
234-
voidhandle_detach_partition(AlterTableStmt*stmt,AlterTableCmd*cmd)
264+
void
265+
handle_detach_partition(AlterTableCmd*cmd)
235266
{
236267
List*proc_name;
237268
FmgrInfoproc_flinfo;
@@ -262,3 +293,63 @@ void handle_detach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
262293
/* Invoke the callback */
263294
FunctionCallInvoke(&proc_fcinfo);
264295
}
296+
297+
/* handle CREATE TABLE .. PARTITION OF <parent> FOR VALUES FROM .. TO .. */
298+
void
299+
handle_create_partition_of(Oidparent_relid,CreateStmt*stmt)
300+
{
301+
Boundstart,
302+
end;
303+
constPartRelationInfo*prel;
304+
ParseState*pstate=make_parsestate(NULL);
305+
PartitionRangeDatum*ldatum,
306+
*rdatum;
307+
Const*lval,
308+
*rval;
309+
A_Const*con;
310+
311+
/* we show errors earlier for these asserts */
312+
Assert(stmt->inhRelations!=NULL);
313+
Assert(stmt->tableElts==NIL);
314+
315+
if (stmt->partbound->strategy!=PARTITION_STRATEGY_RANGE)
316+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
317+
errmsg("pg_pathman only supports queries for range partitions")));
318+
319+
if ((prel=get_pathman_relation_info(parent_relid))==NULL)
320+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
321+
errmsg("table \"%s\" is not partitioned",
322+
get_rel_name_or_relid(parent_relid))));
323+
324+
if (prel->parttype!=PT_RANGE)
325+
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
326+
errmsg("table \"%s\" is not partitioned by RANGE",
327+
get_rel_name_or_relid(parent_relid))));
328+
329+
ldatum= (PartitionRangeDatum*)linitial(stmt->partbound->lowerdatums);
330+
con=castNode(A_Const,ldatum->value);
331+
lval=transform_bound_value(pstate,con,prel->ev_type,prel->ev_typmod);
332+
333+
rdatum= (PartitionRangeDatum*)linitial(stmt->partbound->upperdatums);
334+
con=castNode(A_Const,rdatum->value);
335+
rval=transform_bound_value(pstate,con,prel->ev_type,prel->ev_typmod);
336+
337+
start=lval->constisnull?
338+
MakeBoundInf(MINUS_INFINITY) :
339+
MakeBound(lval->constvalue);
340+
341+
end=rval->constisnull?
342+
MakeBoundInf(PLUS_INFINITY) :
343+
MakeBound(rval->constvalue);
344+
345+
/* more checks */
346+
check_range_available(parent_relid,&start,&end,lval->consttype, true);
347+
348+
/* Create a new RANGE partition and return its Oid */
349+
create_single_range_partition_internal(parent_relid,
350+
&start,
351+
&end,
352+
lval->consttype,
353+
stmt->relation,
354+
stmt->tablespacename);
355+
}

‎src/hooks.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -963,9 +963,9 @@ pathman_process_utility_hook(Node *first_arg,
963963
get_rel_name(relation_oid))));
964964
}
965965
#ifPG_VERSION_NUM >=100000
966-
elseif (is_pathman_related_partitioning_cmd(parsetree))
966+
elseif (is_pathman_related_partitioning_cmd(parsetree,&relation_oid))
967967
{
968-
/* we can handle all the partitioning commands */
968+
/* we can handle all the partitioning commandsin ALTER .. TABLE*/
969969
if (IsA(parsetree,AlterTableStmt))
970970
{
971971
ListCell*lc;
@@ -977,16 +977,21 @@ pathman_process_utility_hook(Node *first_arg,
977977
switch (cmd->subtype)
978978
{
979979
caseAT_AttachPartition:
980-
handle_attach_partition(stmt,cmd);
980+
handle_attach_partition(relation_oid,cmd);
981981
return;
982982
caseAT_DetachPartition:
983-
handle_detach_partition(stmt,cmd);
983+
handle_detach_partition(cmd);
984984
return;
985985
default:
986986
elog(ERROR,"can't handle this command");
987987
}
988988
}
989989
}
990+
elseif (IsA(parsetree,CreateStmt))
991+
{
992+
handle_create_partition_of(relation_oid, (CreateStmt*)parsetree);
993+
return;
994+
}
990995
}
991996
#endif
992997
}

‎src/include/declarative.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
#include"nodes/parsenodes.h"
77

88
voidmodify_declative_partitioning_query(Query*query);
9-
boolis_pathman_related_partitioning_cmd(Node*parsetree);
9+
boolis_pathman_related_partitioning_cmd(Node*parsetree,Oid*parent_relid);
1010

1111
/* actual actions */
12-
voidhandle_attach_partition(AlterTableStmt*stmt,AlterTableCmd*cmd);
13-
voidhandle_detach_partition(AlterTableStmt*stmt,AlterTableCmd*cmd);
12+
voidhandle_attach_partition(Oidparent_relid,AlterTableCmd*cmd);
13+
voidhandle_detach_partition(AlterTableCmd*cmd);
14+
voidhandle_create_partition_of(Oidparent_relid,CreateStmt*stmt);
1415

1516
#endif/* DECLARATIVE_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp