Skip to content

Commit aa45c1e

Browse files
committed
Define compatible version of creating CreateStmt for new partition
1 parent c9f5368 commit aa45c1e

File tree

3 files changed

+73
-49
lines changed

3 files changed

+73
-49
lines changed

src/compat/pg_compat.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "optimizer/clauses.h"
2020
#include "optimizer/pathnode.h"
2121
#include "optimizer/prep.h"
22+
#include "parser/parse_utilcmd.h"
2223
#include "port.h"
2324
#include "utils.h"
2425
#include "utils/lsyscache.h"
@@ -681,3 +682,48 @@ set_append_rel_size_compat(PlannerInfo *root, RelOptInfo *rel, Index rti)
681682

682683
rel->tuples = parent_rows;
683684
}
685+
686+
/*
687+
* Construct the sequence of utility statements to create a new partition
688+
*/
689+
List *
690+
init_createstmts_for_partition(RangeVar *parent_rv,
691+
RangeVar *partition_rv,
692+
char *tablespace)
693+
{
694+
TableLikeClause like_clause;
695+
CreateStmt create_stmt;
696+
List *result;
697+
698+
/* Initialize TableLikeClause structure */
699+
NodeSetTag(&like_clause, T_TableLikeClause);
700+
like_clause.relation = copyObject(parent_rv);
701+
like_clause.options = CREATE_TABLE_LIKE_DEFAULTS |
702+
CREATE_TABLE_LIKE_INDEXES |
703+
CREATE_TABLE_LIKE_STORAGE;
704+
705+
/* Initialize CreateStmt structure */
706+
NodeSetTag(&create_stmt, T_CreateStmt);
707+
create_stmt.relation = copyObject(partition_rv);
708+
create_stmt.tableElts = list_make1(copyObject(&like_clause));
709+
create_stmt.inhRelations = list_make1(copyObject(parent_rv));
710+
create_stmt.ofTypename = NULL;
711+
create_stmt.constraints = NIL;
712+
create_stmt.options = NIL;
713+
create_stmt.oncommit = ONCOMMIT_NOOP;
714+
create_stmt.tablespacename = tablespace;
715+
create_stmt.if_not_exists = false;
716+
717+
#if defined(PGPRO_EE) && PG_VERSION_NUM >= 90600
718+
create_stmt.partition_info = NULL;
719+
#endif
720+
721+
#if PG_VERSION_NUM >= 100000
722+
create_stmt.partbound = NULL;
723+
create_stmt.partspec = NULL;
724+
#endif
725+
726+
result = transformCreateStmt(&create_stmt, NULL);
727+
728+
return result;
729+
}

src/include/compat/pg_compat.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,9 @@ char get_rel_persistence(Oid relid);
263263
*/
264264

265265
void set_append_rel_size_compat(PlannerInfo *root, RelOptInfo *rel, Index rti);
266+
List *init_createstmts_for_partition(RangeVar *parent_rv,
267+
RangeVar *partition_rv,
268+
char *tablespace);
266269

267270

268271
#endif /* PG_COMPAT_H */

src/partition_creation.c

Lines changed: 24 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
#include "miscadmin.h"
3535
#include "parser/parse_func.h"
3636
#include "parser/parse_relation.h"
37-
#include "parser/parse_utilcmd.h"
3837
#include "tcop/utility.h"
3938
#include "utils/builtins.h"
4039
#include "utils/datum.h"
@@ -681,8 +680,6 @@ create_single_partition_internal(Oid parent_relid,
681680

682681
/* Elements of the "CREATE TABLE" query tree */
683682
RangeVar *parent_rv;
684-
TableLikeClause like_clause;
685-
CreateStmt create_stmt;
686683
List *create_stmts;
687684
ListCell *lc;
688685

@@ -702,6 +699,27 @@ create_single_partition_internal(Oid parent_relid,
702699
elog(ERROR, "table \"%s\" is not partitioned",
703700
get_rel_name_or_relid(parent_relid));
704701

702+
/* Do we have to escalate privileges? */
703+
if (need_priv_escalation)
704+
{
705+
/* Get current user's Oid and security context */
706+
GetUserIdAndSecContext(&save_userid, &save_sec_context);
707+
708+
/* Check that user's allowed to spawn partitions */
709+
if (ACLCHECK_OK != pg_class_aclcheck(parent_relid, save_userid,
710+
ACL_SPAWN_PARTITIONS))
711+
ereport(ERROR,
712+
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
713+
errmsg("permission denied for parent relation \"%s\"",
714+
get_rel_name_or_relid(parent_relid)),
715+
errdetail("user is not allowed to create new partitions"),
716+
errhint("consider granting INSERT privilege")));
717+
718+
/* Become superuser in order to bypass various ACL checks */
719+
SetUserIdAndSecContext(BOOTSTRAP_SUPERUSERID,
720+
save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
721+
}
722+
705723
/* Cache parent's namespace and name */
706724
parent_name = get_rel_name(parent_relid);
707725
parent_nsp = get_rel_namespace(parent_relid);
@@ -725,52 +743,9 @@ create_single_partition_internal(Oid parent_relid,
725743
if (!tablespace)
726744
tablespace = get_tablespace_name(get_rel_tablespace(parent_relid));
727745

728-
/* Initialize TableLikeClause structure */
729-
NodeSetTag(&like_clause, T_TableLikeClause);
730-
like_clause.relation = copyObject(parent_rv);
731-
like_clause.options = CREATE_TABLE_LIKE_DEFAULTS |
732-
CREATE_TABLE_LIKE_INDEXES |
733-
CREATE_TABLE_LIKE_STORAGE;
734-
735-
/* Initialize CreateStmt structure */
736-
NodeSetTag(&create_stmt, T_CreateStmt);
737-
create_stmt.relation = copyObject(partition_rv);
738-
create_stmt.tableElts = list_make1(copyObject(&like_clause));
739-
create_stmt.inhRelations = list_make1(copyObject(parent_rv));
740-
create_stmt.ofTypename = NULL;
741-
create_stmt.constraints = NIL;
742-
create_stmt.options = NIL;
743-
create_stmt.oncommit = ONCOMMIT_NOOP;
744-
create_stmt.tablespacename = tablespace;
745-
create_stmt.if_not_exists = false;
746-
747-
#if defined(PGPRO_EE) && PG_VERSION_NUM >= 90600
748-
create_stmt.partition_info = NULL;
749-
#endif
750-
751-
/* Do we have to escalate privileges? */
752-
if (need_priv_escalation)
753-
{
754-
/* Get current user's Oid and security context */
755-
GetUserIdAndSecContext(&save_userid, &save_sec_context);
756-
757-
/* Check that user's allowed to spawn partitions */
758-
if (ACLCHECK_OK != pg_class_aclcheck(parent_relid, save_userid,
759-
ACL_SPAWN_PARTITIONS))
760-
ereport(ERROR,
761-
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
762-
errmsg("permission denied for parent relation \"%s\"",
763-
get_rel_name_or_relid(parent_relid)),
764-
errdetail("user is not allowed to create new partitions"),
765-
errhint("consider granting INSERT privilege")));
766-
767-
/* Become superuser in order to bypass various ACL checks */
768-
SetUserIdAndSecContext(BOOTSTRAP_SUPERUSERID,
769-
save_sec_context | SECURITY_LOCAL_USERID_CHANGE);
770-
}
771-
772-
/* Generate columns using the parent table */
773-
create_stmts = transformCreateStmt(&create_stmt, NULL);
746+
/* Obtain the sequence of Stmts to create partition and link it to parent */
747+
create_stmts = init_createstmts_for_partition(parent_rv, partition_rv,
748+
tablespace);
774749

775750
/* Create the partition and all required relations */
776751
foreach (lc, create_stmts)

0 commit comments

Comments
 (0)