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- bool is_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 int cnt = 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- int subtype = cmd -> subtype ;
72-
73- if (subtype < 0 )
74- subtype = - subtype ;
75-
76- switch (subtype )
83+ switch (abs (cmd -> subtype ))
7784 {
7885 case AT_AttachPartition :
7986 case AT_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+ 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+ }
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- void handle_attach_partition (AlterTableStmt * stmt , AlterTableCmd * cmd )
187+ void
188+ handle_attach_partition (Oid parent_relid , AlterTableCmd * cmd )
161189{
162- Oid parent_relid ,
163- partition_relid ,
190+ Oid partition_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- void handle_detach_partition (AlterTableStmt * stmt , AlterTableCmd * cmd )
264+ void
265+ handle_detach_partition (AlterTableCmd * cmd )
235266{
236267 List * proc_name ;
237268 FmgrInfo proc_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 (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