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{
6264if (IsA (parsetree ,AlterTableStmt ))
6365{
6466ListCell * lc ;
6567AlterTableStmt * stmt = (AlterTableStmt * )parsetree ;
6668int 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+ */
6880foreach (lc ,stmt -> cmds )
6981{
7082AlterTableCmd * 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{
7885case AT_AttachPartition :
7986case 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 );
8592continue ;
8693default :
8794cnt ++ ;
@@ -90,6 +97,26 @@ bool is_pathman_related_partitioning_cmd(Node *parsetree)
9097
9198return (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+ }
93120return 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 ,
164191proc_args []= {REGCLASSOID ,REGCLASSOID ,
165192ANYELEMENTOID ,ANYELEMENTOID };
166193
@@ -181,7 +208,10 @@ void handle_attach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
181208
182209Assert (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+
185215if ((prel = get_pathman_relation_info (parent_relid ))== NULL )
186216elog (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{
236267List * proc_name ;
237268FmgrInfo proc_flinfo ;
@@ -262,3 +293,63 @@ void handle_detach_partition(AlterTableStmt *stmt, AlterTableCmd *cmd)
262293/* Invoke the callback */
263294FunctionCallInvoke (& 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+ }