1
1
#include "declarative.h"
2
2
#include "utils.h"
3
+ #include "partition_creation.h"
3
4
4
5
#include "fmgr.h"
5
6
#include "access/htup_details.h"
@@ -57,31 +58,37 @@ modify_declative_partitioning_query(Query *query)
57
58
}
58
59
59
60
/* is it one of declarative partitioning commands? */
60
- bool is_pathman_related_partitioning_cmd (Node * parsetree )
61
+ bool
62
+ is_pathman_related_partitioning_cmd (Node * parsetree , Oid * parent_relid )
61
63
{
62
64
if (IsA (parsetree , AlterTableStmt ))
63
65
{
64
66
ListCell * lc ;
65
67
AlterTableStmt * stmt = (AlterTableStmt * ) parsetree ;
66
68
int cnt = 0 ;
67
69
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
+ */
68
80
foreach (lc , stmt -> cmds )
69
81
{
70
82
AlterTableCmd * cmd = (AlterTableCmd * ) lfirst (lc );
71
- int subtype = cmd -> subtype ;
72
-
73
- if (subtype < 0 )
74
- subtype = - subtype ;
75
-
76
- switch (subtype )
83
+ switch (abs (cmd -> subtype ))
77
84
{
78
85
case AT_AttachPartition :
79
86
case AT_DetachPartition :
80
87
/*
81
- * we need to fix all subtypes,
88
+ * We need to fix all subtypes,
82
89
* possibly we're not going to handle this
83
90
*/
84
- cmd -> subtype = - (cmd -> subtype );
91
+ cmd -> subtype = abs (cmd -> subtype );
85
92
continue ;
86
93
default :
87
94
cnt ++ ;
@@ -90,6 +97,26 @@ bool is_pathman_related_partitioning_cmd(Node *parsetree)
90
97
91
98
return (cnt == 0 );
92
99
}
100
+ else if (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
+ }
93
120
return false;
94
121
}
95
122
@@ -157,10 +184,10 @@ transform_bound_value(ParseState *pstate, A_Const *con,
157
184
}
158
185
159
186
/* handle ALTER TABLE .. ATTACH PARTITION command */
160
- void handle_attach_partition (AlterTableStmt * stmt , AlterTableCmd * cmd )
187
+ void
188
+ handle_attach_partition (Oid parent_relid , AlterTableCmd * cmd )
161
189
{
162
- Oid parent_relid ,
163
- partition_relid ,
190
+ Oid partition_relid ,
164
191
proc_args [] = { REGCLASSOID , REGCLASSOID ,
165
192
ANYELEMENTOID , ANYELEMENTOID };
166
193
@@ -181,7 +208,10 @@ void handle_attach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
181
208
182
209
Assert (cmd -> subtype == AT_AttachPartition );
183
210
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
+
185
215
if ((prel = get_pathman_relation_info (parent_relid )) == NULL )
186
216
elog (ERROR , "relation is not partitioned" );
187
217
@@ -231,7 +261,8 @@ void handle_attach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
231
261
}
232
262
233
263
/* handle ALTER TABLE .. DETACH PARTITION command */
234
- void handle_detach_partition (AlterTableStmt * stmt , AlterTableCmd * cmd )
264
+ void
265
+ handle_detach_partition (AlterTableCmd * cmd )
235
266
{
236
267
List * proc_name ;
237
268
FmgrInfo proc_flinfo ;
@@ -262,3 +293,63 @@ void handle_detach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
262
293
/* Invoke the callback */
263
294
FunctionCallInvoke (& proc_fcinfo );
264
295
}
296
+
297
+ /* handle CREATE TABLE .. PARTITION OF <parent> FOR VALUES FROM .. TO .. */
298
+ void
299
+ handle_create_partition_of (Oid parent_relid , CreateStmt * stmt )
300
+ {
301
+ Bound start ,
302
+ end ;
303
+ const PartRelationInfo * 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
+ }
0 commit comments