Revert support for ALTER TABLE ... MERGE/SPLIT PARTITION(S) commands
authorAlexander Korotkov <akorotkov@postgresql.org>
Sat, 24 Aug 2024 15:48:48 +0000 (18:48 +0300)
committerAlexander Korotkov <akorotkov@postgresql.org>
Sat, 24 Aug 2024 15:48:48 +0000 (18:48 +0300)
This commit reverts 1adf16b8fb87c21bb941, and subsequent fixes and
improvements including df64c81ca9c99ef1811a9dfcac8e15885742b9f8,
842c9b2705fcf80c5d5f96c7381c4cf4fc7cb54b60ae37a8bc259c96fa8f,
449cdcd4863ca43dbbb62a679ae94e3a82c689fdfbd4321fd5d53a4286d7,
c0868966254e5d6c409104158e7fa3.

The reason for reverting is security issues related to repeatable name lookups
(CVE-2014-0062).  Even though 04158e7fa3 solved part of the problem, there
are still remaining issues, which aren't feasible to even carefully analyze
before the RC deadline.

Reported-by: Noah Misch, Robert Haas
Discussion: https://postgr.es/m/20240808171351.a9.nmisch%40google.com
Backpatch-through: 17

25 files changed:
doc/src/sgml/ddl.sgml
doc/src/sgml/ref/alter_table.sgml
src/backend/commands/tablecmds.c
src/backend/parser/gram.y
src/backend/parser/parse_utilcmd.c
src/backend/partitioning/partbounds.c
src/backend/tcop/utility.c
src/backend/utils/adt/ruleutils.c
src/bin/psql/tab-complete.c
src/include/nodes/parsenodes.h
src/include/parser/kwlist.h
src/include/partitioning/partbounds.h
src/include/utils/ruleutils.h
src/test/isolation/expected/partition-merge.out [deleted file]
src/test/isolation/expected/partition-split.out [deleted file]
src/test/isolation/isolation_schedule
src/test/isolation/specs/partition-merge.spec [deleted file]
src/test/isolation/specs/partition-split.spec [deleted file]
src/test/modules/test_ddl_deparse/test_ddl_deparse.c
src/test/regress/expected/partition_merge.out [deleted file]
src/test/regress/expected/partition_split.out [deleted file]
src/test/regress/parallel_schedule
src/test/regress/sql/partition_merge.sql [deleted file]
src/test/regress/sql/partition_split.sql [deleted file]
src/tools/pgindent/typedefs.list

index 626d35514cc3959253b039d03f86275115515bcb..b671858627b869a91a7b936ada90dad12ed960eb 100644 (file)
@@ -4355,44 +4355,6 @@ ALTER INDEX measurement_city_id_logdate_key
 ...
 </programlisting>
     </para>
-
-    <para>
-     There is also an option for merging multiple table partitions into
-     a single partition using the
-     <link linkend="sql-altertable-merge-partitions"><command>ALTER TABLE ... MERGE PARTITIONS</command></link>.
-     This feature simplifies the management of partitioned tables by allowing
-     users to combine partitions that are no longer needed as
-     separate entities.  It's important to note that this operation is not
-     supported for hash-partitioned tables and acquires an
-     <literal>ACCESS EXCLUSIVE</literal> lock, which could impact high-load
-     systems due to the lock's restrictive nature.  For example, we can
-     merge three monthly partitions into one quarter partition:
-<programlisting>
-ALTER TABLE measurement
-    MERGE PARTITIONS (measurement_y2006m01,
-                      measurement_y2006m02,
-                      measurement_y2006m03) INTO measurement_y2006q1;
-</programlisting>
-    </para>
-
-    <para>
-     Similarly to merging multiple table partitions, there is an option for
-     splitting a single partition into multiple using the
-     <link linkend="sql-altertable-split-partition"><command>ALTER TABLE ... SPLIT PARTITION</command></link>.
-     This feature could come in handy when one partition grows too big
-     and needs to be split into multiple.  It's important to note that
-     this operation is not supported for hash-partitioned tables and acquires
-     an <literal>ACCESS EXCLUSIVE</literal> lock, which could impact high-load
-     systems due to the lock's restrictive nature.  For example, we can split
-     the quarter partition back to monthly partitions:
-<programlisting>
-ALTER TABLE measurement SPLIT PARTITION measurement_y2006q1 INTO
-   (PARTITION measurement_y2006m01 FOR VALUES FROM ('2006-01-01') TO ('2006-02-01'),
-    PARTITION measurement_y2006m02 FOR VALUES FROM ('2006-02-01') TO ('2006-03-01'),
-    PARTITION measurement_y2006m03 FOR VALUES FROM ('2006-03-01') TO ('2006-04-01'));
-</programlisting>
-    </para>
-
    </sect3>
 
    <sect3 id="ddl-partitioning-declarative-limitations">
index 6a2822adad739092c11899a38cae6955fadd58df..1a49f321cf702c9ca0352dd427049731f2f2d557 100644 (file)
@@ -37,13 +37,6 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
     ATTACH PARTITION <replaceable class="parameter">partition_name</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
 ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
     DETACH PARTITION <replaceable class="parameter">partition_name</replaceable> [ CONCURRENTLY | FINALIZE ]
-ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
-    SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO
-        (PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT },
-         PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])
-ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
-    MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...])
-        INTO <replaceable class="parameter">partition_name</replaceable>
 
 <phrase>where <replaceable class="parameter">action</replaceable> is one of:</phrase>
 
@@ -1124,140 +1117,14 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     </listitem>
    </varlistentry>
 
-   <varlistentry id="sql-altertable-split-partition">
-    <term><literal>SPLIT PARTITION <replaceable class="parameter">partition_name</replaceable> INTO (PARTITION <replaceable class="parameter">partition_name1</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }, PARTITION <replaceable class="parameter">partition_name2</replaceable> { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT } [, ...])</literal></term>
-
-    <listitem>
-     <para>
-      This form splits a single partition of the target table. Hash-partitioning
-      is not supported. Bounds of new partitions should not overlap with new and
-      existing partitions (except <replaceable class="parameter">partition_name</replaceable>).
-      If the split partition is a DEFAULT partition, one of the new partitions must be DEFAULT.
-      In case one of the new partitions or one of existing partitions is DEFAULT,
-      new partitions <replaceable class="parameter">partition_name1</replaceable>,
-      <replaceable class="parameter">partition_name2</replaceable>, ... can have spaces
-      between partitions bounds.  If the partitioned table does not have a DEFAULT
-      partition, the DEFAULT partition can be defined as one of the new partitions.
-     </para>
-     <para>
-      In case new partitions do not contain a DEFAULT partition and the partitioned table
-      does not have a DEFAULT partition, the following must be true: sum bounds of
-      new partitions <replaceable class="parameter">partition_name1</replaceable>,
-      <replaceable class="parameter">partition_name2</replaceable>, ... should be
-      equal to bound of split partition <replaceable class="parameter">partition_name</replaceable>.
-      One of the new partitions <replaceable class="parameter">partition_name1</replaceable>,
-      <replaceable class="parameter">partition_name2</replaceable>, ... can have
-      the same name as split partition <replaceable class="parameter">partition_name</replaceable>
-      (this is suitable in case of splitting a DEFAULT partition: we split it, but after
-      splitting we have a partition with the same name).
-      Only simple, non-partitioned partition can be split.
-     </para>
-     <para>
-      The new partitions will be created the same as tables created with the
-      SQL command <literal>CREATE TABLE <replaceable class="parameter">partition_nameN</replaceable> (LIKE <replaceable class="parameter">name</replaceable> INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)</literal>.
-      The indexes and identity are created later, after moving the data
-      into the new partitions.
-      Extended statistics aren't copied from the parent table, for consistency with
-      <command>CREATE TABLE PARTITION OF</command>.
-
-      New partitions will have the same table access method as the parent.
-      If the parent table is persistent then new partitions are created
-      persistent.  If the parent table is temporary then new partitions
-      are also created temporary.  New partitions will also be created in
-      the same tablespace as the parent.
-     </para>
-     <note>
-      <para>
-       This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
-       This is a significant limitation, which limits the usage of this
-       command with large partitioned tables under a high load.
-      </para>
-     </note>
-    </listitem>
-   </varlistentry>
-
-   <varlistentry id="sql-altertable-merge-partitions">
-    <term><literal>MERGE PARTITIONS (<replaceable class="parameter">partition_name1</replaceable>, <replaceable class="parameter">partition_name2</replaceable> [, ...]) INTO <replaceable class="parameter">partition_name</replaceable></literal></term>
-
-    <listitem>
-     <para>
-      This form merges several partitions into the one partition of the target table.
-      Hash-partitioning is not supported.  If DEFAULT partition is not in the
-      list of partitions <replaceable class="parameter">partition_name1</replaceable>,
-      <replaceable class="parameter">partition_name2</replaceable> [, ...]:
-      <itemizedlist>
-       <listitem>
-        <para>
-         For range-partitioned tables it is necessary that the ranges
-         of the partitions <replaceable class="parameter">partition_name1</replaceable>,
-         <replaceable class="parameter">partition_name2</replaceable> [, ...] can
-         be merged into one range without spaces and overlaps (otherwise an error
-         will be generated).  The combined range will be the range for the partition
-         <replaceable class="parameter">partition_name</replaceable>.
-        </para>
-       </listitem>
-       <listitem>
-        <para>
-         For list-partitioned tables the value lists of all partitions
-         <replaceable class="parameter">partition_name1</replaceable>,
-         <replaceable class="parameter">partition_name2</replaceable> [, ...] are
-         combined and form the list of values of partition
-         <replaceable class="parameter">partition_name</replaceable>.
-        </para>
-       </listitem>
-      </itemizedlist>
-      If DEFAULT partition is in the list of partitions <replaceable class="parameter">partition_name1</replaceable>,
-      <replaceable class="parameter">partition_name2</replaceable> [, ...]:
-      <itemizedlist>
-       <listitem>
-        <para>
-         The partition <replaceable class="parameter">partition_name</replaceable>
-         will be the DEFAULT partition.
-        </para>
-       </listitem>
-       <listitem>
-        <para>
-         For range- and list-partitioned tables the ranges and lists of values
-         of the merged partitions can be any.
-        </para>
-       </listitem>
-      </itemizedlist>
-      The new partition <replaceable class="parameter">partition_name</replaceable>
-      can have the same name as one of the merged partitions.  Only simple,
-      non-partitioned partitions can be merged.
-     </para>
-     <para>
-      The new partition will be created the same as a table created with the
-      SQL command <literal>CREATE TABLE <replaceable class="parameter">partition_name</replaceable> (LIKE <replaceable class="parameter">name</replaceable> INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)</literal>.
-      The indexes and identity are created later, after moving the data
-      into the new partition.
-      Extended statistics aren't copied from the parent table, for consistency with
-      <command>CREATE TABLE PARTITION OF</command>.
-      The new partition will have the same table access method as the parent.
-      If the parent table is persistent then the new partition is created
-      persistent.  If the parent table is temporary then the new partition
-      is also created temporary.  The new partition will also be created in
-      the same tablespace as the parent.
-     </para>
-     <note>
-      <para>
-       This command acquires an <literal>ACCESS EXCLUSIVE</literal> lock.
-       This is a significant limitation, which limits the usage of this
-       command with large partitioned tables under a high load.
-      </para>
-     </note>
-    </listitem>
-   </varlistentry>
-
   </variablelist>
   </para>
 
   <para>
    All the forms of ALTER TABLE that act on a single table, except
    <literal>RENAME</literal>, <literal>SET SCHEMA</literal>,
-   <literal>ATTACH PARTITION</literal>, <literal>DETACH PARTITION</literal>,
-   <literal>SPLIT PARTITION</literal>, and <literal>MERGE PARTITIONS</literal>
-   can be combined into
+   <literal>ATTACH PARTITION</literal>, and
+   <literal>DETACH PARTITION</literal> can be combined into
    a list of multiple alterations to be applied together.  For example, it
    is possible to add several columns and/or alter the type of several
    columns in a single command.  This is particularly useful with large
@@ -1500,8 +1367,7 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
       <term><replaceable class="parameter">partition_name</replaceable></term>
       <listitem>
        <para>
-        The name of the table to attach as a new partition or to detach from this table,
-        or the name of split partition, or the name of the new merged partition.
+        The name of the table to attach as a new partition or to detach from this table.
        </para>
       </listitem>
      </varlistentry>
@@ -1917,31 +1783,6 @@ ALTER TABLE measurement
     DETACH PARTITION measurement_y2015m12;
 </programlisting></para>
 
-  <para>
-   To split a single partition of the range-partitioned table:
-<programlisting>
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2023 INTO
-   (PARTITION sales_feb2023 FOR VALUES FROM ('2023-02-01') TO ('2023-03-01'),
-    PARTITION sales_mar2023 FOR VALUES FROM ('2023-03-01') TO ('2023-04-01'),
-    PARTITION sales_apr2023 FOR VALUES FROM ('2023-04-01') TO ('2023-05-01'));
-</programlisting></para>
-
-  <para>
-   To split a single partition of the list-partitioned table:
-<programlisting>
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-   (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-    PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-    PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-</programlisting></para>
-
-  <para>
-   To merge several partitions into one partition of the target table:
-<programlisting>
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central)
-    INTO sales_all;
-</programlisting></para>
-
  </refsect1>
 
  <refsect1>
index 52ce6b0c92a4572986716d979ecf5043161395cc..dac39df83aca3a10cf5f8821591901d177682177 100644 (file)
@@ -657,11 +657,6 @@ static void ATDetachCheckNoForeignKeyRefs(Relation partition);
 static char GetAttributeCompression(Oid atttypid, const char *compression);
 static char GetAttributeStorage(Oid atttypid, const char *storagemode);
 
-static void ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab,
-                                Relation rel, PartitionCmd *cmd,
-                                AlterTableUtilityContext *context);
-static void ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
-                                 PartitionCmd *cmd, AlterTableUtilityContext *context);
 
 /* ----------------------------------------------------------------
  *     DefineRelation
@@ -4672,14 +4667,6 @@ AlterTableGetLockLevel(List *cmds)
                cmd_lockmode = ShareUpdateExclusiveLock;
                break;
 
-           case AT_SplitPartition:
-               cmd_lockmode = AccessExclusiveLock;
-               break;
-
-           case AT_MergePartitions:
-               cmd_lockmode = AccessExclusiveLock;
-               break;
-
            case AT_CheckNotNull:
 
                /*
@@ -5106,16 +5093,6 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
            /* No command-specific prep needed */
            pass = AT_PASS_MISC;
            break;
-       case AT_SplitPartition:
-           ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
-           /* No command-specific prep needed */
-           pass = AT_PASS_MISC;
-           break;
-       case AT_MergePartitions:
-           ATSimplePermissions(cmd->subtype, rel, ATT_TABLE);
-           /* No command-specific prep needed */
-           pass = AT_PASS_MISC;
-           break;
        default:                /* oops */
            elog(ERROR, "unrecognized alter table type: %d",
                 (int) cmd->subtype);
@@ -5512,22 +5489,6 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab,
        case AT_DetachPartitionFinalize:
            address = ATExecDetachPartitionFinalize(rel, ((PartitionCmd *) cmd->def)->name);
            break;
-       case AT_SplitPartition:
-           cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode,
-                                     cur_pass, context);
-           Assert(cmd != NULL);
-           Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
-           ATExecSplitPartition(wqueue, tab, rel, (PartitionCmd *) cmd->def,
-                                context);
-           break;
-       case AT_MergePartitions:
-           cmd = ATParseTransformCmd(wqueue, tab, rel, cmd, false, lockmode,
-                                     cur_pass, context);
-           Assert(cmd != NULL);
-           Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
-           ATExecMergePartitions(wqueue, tab, rel, (PartitionCmd *) cmd->def,
-                                 context);
-           break;
        default:                /* oops */
            elog(ERROR, "unrecognized alter table type: %d",
                 (int) cmd->subtype);
@@ -6516,10 +6477,6 @@ alter_table_type_to_string(AlterTableType cmdtype)
            return "DETACH PARTITION";
        case AT_DetachPartitionFinalize:
            return "DETACH PARTITION ... FINALIZE";
-       case AT_SplitPartition:
-           return "SPLIT PARTITION";
-       case AT_MergePartitions:
-           return "MERGE PARTITIONS";
        case AT_AddIdentity:
            return "ALTER COLUMN ... ADD IDENTITY";
        case AT_SetIdentity:
@@ -18328,37 +18285,6 @@ QueuePartitionConstraintValidation(List **wqueue, Relation scanrel,
    }
 }
 
-/*
- * attachPartitionTable: attach a new partition to the partitioned table
- *
- * wqueue: the ALTER TABLE work queue; can be NULL when not running as part
- *   of an ALTER TABLE sequence.
- * rel: partitioned relation;
- * attachrel: relation of attached partition;
- * bound: bounds of attached relation.
- */
-static void
-attachPartitionTable(List **wqueue, Relation rel, Relation attachrel, PartitionBoundSpec *bound)
-{
-   /* OK to create inheritance.  Rest of the checks performed there */
-   CreateInheritance(attachrel, rel, true);
-
-   /* Update the pg_class entry. */
-   StorePartitionBound(attachrel, rel, bound);
-
-   /* Ensure there exists a correct set of indexes in the partition. */
-   AttachPartitionEnsureIndexes(wqueue, rel, attachrel);
-
-   /* and triggers */
-   CloneRowTriggersToPartition(rel, attachrel);
-
-   /*
-    * Clone foreign key constraints.  Callee is responsible for setting up
-    * for phase 3 constraint verification.
-    */
-   CloneForeignKeyConstraints(wqueue, rel, attachrel);
-}
-
 /*
  * ALTER TABLE <name> ATTACH PARTITION <partition-name> FOR VALUES
  *
@@ -18561,8 +18487,23 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd,
    check_new_partition_bound(RelationGetRelationName(attachrel), rel,
                              cmd->bound, pstate);
 
-   /* Attach a new partition to the partitioned table. */
-   attachPartitionTable(wqueue, rel, attachrel, cmd->bound);
+   /* OK to create inheritance.  Rest of the checks performed there */
+   CreateInheritance(attachrel, rel, true);
+
+   /* Update the pg_class entry. */
+   StorePartitionBound(attachrel, rel, cmd->bound);
+
+   /* Ensure there exists a correct set of indexes in the partition. */
+   AttachPartitionEnsureIndexes(wqueue, rel, attachrel);
+
+   /* and triggers */
+   CloneRowTriggersToPartition(rel, attachrel);
+
+   /*
+    * Clone foreign key constraints.  Callee is responsible for setting up
+    * for phase 3 constraint verification.
+    */
+   CloneForeignKeyConstraints(wqueue, rel, attachrel);
 
    /*
     * Generate partition constraint from the partition bound specification.
@@ -20077,729 +20018,3 @@ GetAttributeStorage(Oid atttypid, const char *storagemode)
 
    return cstorage;
 }
-
-/*
- * Struct with context of new partition for inserting rows from split partition
- */
-typedef struct SplitPartitionContext
-{
-   ExprState  *partqualstate;  /* expression for checking slot for partition
-                                * (NULL for DEFAULT partition) */
-   BulkInsertState bistate;    /* state of bulk inserts for partition */
-   TupleTableSlot *dstslot;    /* slot for inserting row into partition */
-   Relation    partRel;        /* relation for partition */
-} SplitPartitionContext;
-
-
-/*
- * createSplitPartitionContext: create context for partition and fill it
- */
-static SplitPartitionContext *
-createSplitPartitionContext(Relation partRel)
-{
-   SplitPartitionContext *pc;
-
-   pc = (SplitPartitionContext *) palloc0(sizeof(SplitPartitionContext));
-   pc->partRel = partRel;
-
-   /*
-    * Prepare a BulkInsertState for table_tuple_insert. The FSM is empty, so
-    * don't bother using it.
-    */
-   pc->bistate = GetBulkInsertState();
-
-   /* Create tuple slot for new partition. */
-   pc->dstslot = MakeSingleTupleTableSlot(RelationGetDescr(pc->partRel),
-                                          table_slot_callbacks(pc->partRel));
-   ExecStoreAllNullTuple(pc->dstslot);
-
-   return pc;
-}
-
-/*
- * deleteSplitPartitionContext: delete context for partition
- */
-static void
-deleteSplitPartitionContext(SplitPartitionContext *pc, int ti_options)
-{
-   ExecDropSingleTupleTableSlot(pc->dstslot);
-   FreeBulkInsertState(pc->bistate);
-
-   table_finish_bulk_insert(pc->partRel, ti_options);
-
-   pfree(pc);
-}
-
-/*
- * moveSplitTableRows: scan split partition (splitRel) of partitioned table
- * (rel) and move rows into new partitions.
- *
- * New partitions description:
- * partlist: list of pointers to SinglePartitionSpec structures.
- * newPartRels: list of Relations.
- * defaultPartOid: oid of DEFAULT partition, for table rel.
- */
-static void
-moveSplitTableRows(Relation rel, Relation splitRel, List *partlist, List *newPartRels, Oid defaultPartOid)
-{
-   /* The FSM is empty, so don't bother using it. */
-   int         ti_options = TABLE_INSERT_SKIP_FSM;
-   CommandId   mycid;
-   EState     *estate;
-   ListCell   *listptr,
-              *listptr2;
-   TupleTableSlot *srcslot;
-   ExprContext *econtext;
-   TableScanDesc scan;
-   Snapshot    snapshot;
-   MemoryContext oldCxt;
-   List       *partContexts = NIL;
-   TupleConversionMap *tuple_map;
-   SplitPartitionContext *defaultPartCtx = NULL,
-              *pc;
-   bool        isOldDefaultPart = false;
-
-   mycid = GetCurrentCommandId(true);
-
-   estate = CreateExecutorState();
-
-   forboth(listptr, partlist, listptr2, newPartRels)
-   {
-       SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr);
-
-       pc = createSplitPartitionContext((Relation) lfirst(listptr2));
-
-       if (sps->bound->is_default)
-       {
-           /* We should not create constraint for detached DEFAULT partition. */
-           defaultPartCtx = pc;
-       }
-       else
-       {
-           List       *partConstraint;
-
-           /* Build expression execution states for partition check quals. */
-           partConstraint = get_qual_from_partbound(rel, sps->bound);
-           partConstraint =
-               (List *) eval_const_expressions(NULL,
-                                               (Node *) partConstraint);
-           /* Make boolean expression for ExecCheck(). */
-           partConstraint = list_make1(make_ands_explicit(partConstraint));
-
-           /*
-            * Map the vars in the constraint expression from rel's attnos to
-            * splitRel's.
-            */
-           partConstraint = map_partition_varattnos(partConstraint,
-                                                    1, splitRel, rel);
-
-           pc->partqualstate =
-               ExecPrepareExpr((Expr *) linitial(partConstraint), estate);
-           Assert(pc->partqualstate != NULL);
-       }
-
-       /* Store partition context into list. */
-       partContexts = lappend(partContexts, pc);
-   }
-
-   /*
-    * Create partition context for DEFAULT partition. We can insert values
-    * into this partition in case spaces with values between new partitions.
-    */
-   if (!defaultPartCtx && OidIsValid(defaultPartOid))
-   {
-       /* Indicate that we allocate context for old DEFAULT partition */
-       isOldDefaultPart = true;
-       defaultPartCtx = createSplitPartitionContext(table_open(defaultPartOid, AccessExclusiveLock));
-   }
-
-   econtext = GetPerTupleExprContext(estate);
-
-   /* Create necessary tuple slot. */
-   srcslot = MakeSingleTupleTableSlot(RelationGetDescr(splitRel),
-                                      table_slot_callbacks(splitRel));
-
-   /*
-    * Map computing for moving attributes of split partition to new partition
-    * (for first new partition, but other new partitions can use the same
-    * map).
-    */
-   pc = (SplitPartitionContext *) lfirst(list_head(partContexts));
-   tuple_map = convert_tuples_by_name(RelationGetDescr(splitRel),
-                                      RelationGetDescr(pc->partRel));
-
-   /* Scan through the rows. */
-   snapshot = RegisterSnapshot(GetLatestSnapshot());
-   scan = table_beginscan(splitRel, snapshot, 0, NULL);
-
-   /*
-    * Switch to per-tuple memory context and reset it for each tuple
-    * produced, so we don't leak memory.
-    */
-   oldCxt = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
-
-   while (table_scan_getnextslot(scan, ForwardScanDirection, srcslot))
-   {
-       bool        found = false;
-       TupleTableSlot *insertslot;
-
-       /* Extract data from old tuple. */
-       slot_getallattrs(srcslot);
-
-       econtext->ecxt_scantuple = srcslot;
-
-       /* Search partition for current slot srcslot. */
-       foreach(listptr, partContexts)
-       {
-           pc = (SplitPartitionContext *) lfirst(listptr);
-
-           if (pc->partqualstate /* skip DEFAULT partition */ &&
-               ExecCheck(pc->partqualstate, econtext))
-           {
-               found = true;
-               break;
-           }
-           ResetExprContext(econtext);
-       }
-       if (!found)
-       {
-           /* Use DEFAULT partition if it exists. */
-           if (defaultPartCtx)
-               pc = defaultPartCtx;
-           else
-               ereport(ERROR,
-                       (errcode(ERRCODE_CHECK_VIOLATION),
-                        errmsg("can not find partition for split partition row"),
-                        errtable(splitRel)));
-       }
-
-       if (tuple_map)
-       {
-           /* Need to use map to copy attributes. */
-           insertslot = execute_attr_map_slot(tuple_map->attrMap, srcslot, pc->dstslot);
-       }
-       else
-       {
-           /* Copy attributes directly. */
-           insertslot = pc->dstslot;
-
-           ExecClearTuple(insertslot);
-
-           memcpy(insertslot->tts_values, srcslot->tts_values,
-                  sizeof(Datum) * srcslot->tts_nvalid);
-           memcpy(insertslot->tts_isnull, srcslot->tts_isnull,
-                  sizeof(bool) * srcslot->tts_nvalid);
-
-           ExecStoreVirtualTuple(insertslot);
-       }
-
-       /* Write the tuple out to the new relation. */
-       table_tuple_insert(pc->partRel, insertslot, mycid,
-                          ti_options, pc->bistate);
-
-       ResetExprContext(econtext);
-
-       CHECK_FOR_INTERRUPTS();
-   }
-
-   MemoryContextSwitchTo(oldCxt);
-
-   table_endscan(scan);
-   UnregisterSnapshot(snapshot);
-
-   if (tuple_map)
-       free_conversion_map(tuple_map);
-
-   ExecDropSingleTupleTableSlot(srcslot);
-
-   FreeExecutorState(estate);
-
-   foreach(listptr, partContexts)
-       deleteSplitPartitionContext((SplitPartitionContext *) lfirst(listptr), ti_options);
-
-   /* Need to close table and free buffers for DEFAULT partition. */
-   if (isOldDefaultPart)
-   {
-       Relation    defaultPartRel = defaultPartCtx->partRel;
-
-       deleteSplitPartitionContext(defaultPartCtx, ti_options);
-       /* Keep the lock until commit. */
-       table_close(defaultPartRel, NoLock);
-   }
-}
-
-/*
- * createPartitionTable: create table for a new partition with given name
- * (newPartName) like table (modelRel)
- *
- * Emulates command: CREATE [TEMP] TABLE <newPartName> (LIKE <modelRel's name>
- * INCLUDING ALL EXCLUDING INDEXES EXCLUDING IDENTITY EXCLUDING STATISTICS)
- *
- * Also, this function sets the new partition access method same as parent
- * table access methods (similarly to CREATE TABLE ... PARTITION OF).  It
- * checks that parent and child tables have compatible persistence.
- *
- * Function returns the created relation (locked in AccessExclusiveLock mode).
- */
-static Relation
-createPartitionTable(RangeVar *newPartName, Relation modelRel,
-                    AlterTableUtilityContext *context)
-{
-   CreateStmt *createStmt;
-   TableLikeClause *tlc;
-   PlannedStmt *wrapper;
-   Relation    newRel;
-
-   /* If existing rel is temp, it must belong to this session */
-   if (modelRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP &&
-       !modelRel->rd_islocaltemp)
-       ereport(ERROR,
-               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                errmsg("cannot create as partition of temporary relation of another session")));
-
-   /* New partition should have the same persistence as modelRel */
-   newPartName->relpersistence = modelRel->rd_rel->relpersistence;
-
-   createStmt = makeNode(CreateStmt);
-   createStmt->relation = newPartName;
-   createStmt->tableElts = NIL;
-   createStmt->inhRelations = NIL;
-   createStmt->constraints = NIL;
-   createStmt->options = NIL;
-   createStmt->oncommit = ONCOMMIT_NOOP;
-   createStmt->tablespacename = get_tablespace_name(modelRel->rd_rel->reltablespace);
-   createStmt->if_not_exists = false;
-   createStmt->accessMethod = get_am_name(modelRel->rd_rel->relam);
-
-   tlc = makeNode(TableLikeClause);
-   tlc->relation = makeRangeVar(get_namespace_name(RelationGetNamespace(modelRel)),
-                                RelationGetRelationName(modelRel), -1);
-
-   /*
-    * Indexes will be inherited on "attach new partitions" stage, after data
-    * moving.  We also don't copy the extended statistics for consistency
-    * with CREATE TABLE PARTITION OF.
-    */
-   tlc->options = CREATE_TABLE_LIKE_ALL &
-       ~(CREATE_TABLE_LIKE_INDEXES | CREATE_TABLE_LIKE_IDENTITY | CREATE_TABLE_LIKE_STATISTICS);
-   tlc->relationOid = InvalidOid;
-   tlc->newRelationOid = InvalidOid;
-   createStmt->tableElts = lappend(createStmt->tableElts, tlc);
-
-   /* Need to make a wrapper PlannedStmt. */
-   wrapper = makeNode(PlannedStmt);
-   wrapper->commandType = CMD_UTILITY;
-   wrapper->canSetTag = false;
-   wrapper->utilityStmt = (Node *) createStmt;
-   wrapper->stmt_location = context->pstmt->stmt_location;
-   wrapper->stmt_len = context->pstmt->stmt_len;
-
-   ProcessUtility(wrapper,
-                  context->queryString,
-                  false,
-                  PROCESS_UTILITY_SUBCOMMAND,
-                  NULL,
-                  NULL,
-                  None_Receiver,
-                  NULL);
-
-   /*
-    * Open the new partition with no lock, because we already have
-    * AccessExclusiveLock placed there after creation.
-    */
-   newRel = table_open(tlc->newRelationOid, NoLock);
-
-   /*
-    * We intended to create the partition with the same persistence as the
-    * parent table, but we still need to recheck because that might be
-    * affected by the search_path.  If the parent is permanent, so must be
-    * all of its partitions.
-    */
-   if (modelRel->rd_rel->relpersistence != RELPERSISTENCE_TEMP &&
-       newRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
-       ereport(ERROR,
-               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                errmsg("cannot create a temporary relation as partition of permanent relation \"%s\"",
-                       RelationGetRelationName(modelRel))));
-
-   /* Permanent rels cannot be partitions belonging to temporary parent */
-   if (newRel->rd_rel->relpersistence != RELPERSISTENCE_TEMP &&
-       modelRel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
-       ereport(ERROR,
-               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                errmsg("cannot create a permanent relation as partition of temporary relation \"%s\"",
-                       RelationGetRelationName(modelRel))));
-
-   return newRel;
-}
-
-/*
- * ALTER TABLE <name> SPLIT PARTITION <partition-name> INTO <partition-list>
- */
-static void
-ATExecSplitPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
-                    PartitionCmd *cmd, AlterTableUtilityContext *context)
-{
-   Relation    splitRel;
-   Oid         splitRelOid;
-   char        relname[NAMEDATALEN];
-   Oid         namespaceId;
-   ListCell   *listptr,
-              *listptr2;
-   bool        isSameName = false;
-   char        tmpRelName[NAMEDATALEN];
-   List       *newPartRels = NIL;
-   ObjectAddress object;
-   Oid         defaultPartOid;
-
-   defaultPartOid = get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true));
-
-   /*
-    * We are going to detach and remove this partition: need to use exclusive
-    * lock for preventing DML-queries to the partition.
-    */
-   splitRel = table_openrv(cmd->name, AccessExclusiveLock);
-
-   splitRelOid = RelationGetRelid(splitRel);
-
-   /* Check descriptions of new partitions. */
-   foreach(listptr, cmd->partlist)
-   {
-       Oid         existing_relid;
-       SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr);
-
-       strlcpy(relname, sps->name->relname, NAMEDATALEN);
-
-       /*
-        * Look up the namespace in which we are supposed to create the
-        * partition, check we have permission to create there, lock it
-        * against concurrent drop, and mark stmt->relation as
-        * RELPERSISTENCE_TEMP if a temporary namespace is selected.
-        */
-       sps->name->relpersistence = rel->rd_rel->relpersistence;
-       namespaceId =
-           RangeVarGetAndCheckCreationNamespace(sps->name, NoLock, NULL);
-
-       /*
-        * This would fail later on anyway if the relation already exists. But
-        * by catching it here we can emit a nicer error message.
-        */
-       existing_relid = get_relname_relid(relname, namespaceId);
-       if (existing_relid == splitRelOid && !isSameName)
-           /* One new partition can have the same name as split partition. */
-           isSameName = true;
-       else if (existing_relid != InvalidOid)
-           ereport(ERROR,
-                   (errcode(ERRCODE_DUPLICATE_TABLE),
-                    errmsg("relation \"%s\" already exists", relname)));
-   }
-
-   /* Detach split partition. */
-   RemoveInheritance(splitRel, rel, false);
-   /* Do the final part of detaching. */
-   DetachPartitionFinalize(rel, splitRel, false, defaultPartOid);
-
-   /*
-    * If new partition has the same name as split partition then we should
-    * rename split partition for reusing name.
-    */
-   if (isSameName)
-   {
-       /*
-        * We must bump the command counter to make the split partition tuple
-        * visible for renaming.
-        */
-       CommandCounterIncrement();
-       /* Rename partition. */
-       sprintf(tmpRelName, "split-%u-%X-tmp", RelationGetRelid(rel), MyProcPid);
-       RenameRelationInternal(splitRelOid, tmpRelName, false, false);
-
-       /*
-        * We must bump the command counter to make the split partition tuple
-        * visible after renaming.
-        */
-       CommandCounterIncrement();
-   }
-
-   /* Create new partitions (like split partition), without indexes. */
-   foreach(listptr, cmd->partlist)
-   {
-       SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr);
-       Relation    newPartRel;
-
-       newPartRel = createPartitionTable(sps->name, rel, context);
-       newPartRels = lappend(newPartRels, newPartRel);
-   }
-
-   /* Copy data from split partition to new partitions. */
-   moveSplitTableRows(rel, splitRel, cmd->partlist, newPartRels, defaultPartOid);
-   /* Keep the lock until commit. */
-   table_close(splitRel, NoLock);
-
-   /* Attach new partitions to partitioned table. */
-   forboth(listptr, cmd->partlist, listptr2, newPartRels)
-   {
-       SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr);
-       Relation    newPartRel = (Relation) lfirst(listptr2);
-
-       /*
-        * wqueue = NULL: verification for each cloned constraint is not
-        * needed.
-        */
-       attachPartitionTable(NULL, rel, newPartRel, sps->bound);
-       /* Keep the lock until commit. */
-       table_close(newPartRel, NoLock);
-   }
-
-   /* Drop split partition. */
-   object.classId = RelationRelationId;
-   object.objectId = splitRelOid;
-   object.objectSubId = 0;
-   /* Probably DROP_CASCADE is not needed. */
-   performDeletion(&object, DROP_RESTRICT, 0);
-}
-
-/*
- * moveMergedTablesRows: scan partitions to be merged (mergingPartitionsList)
- * of the partitioned table (rel) and move rows into the new partition
- * (newPartRel).
- */
-static void
-moveMergedTablesRows(Relation rel, List *mergingPartitionsList,
-                    Relation newPartRel)
-{
-   CommandId   mycid;
-
-   /* The FSM is empty, so don't bother using it. */
-   int         ti_options = TABLE_INSERT_SKIP_FSM;
-   ListCell   *listptr;
-   BulkInsertState bistate;    /* state of bulk inserts for partition */
-   TupleTableSlot *dstslot;
-
-   mycid = GetCurrentCommandId(true);
-
-   /* Prepare a BulkInsertState for table_tuple_insert. */
-   bistate = GetBulkInsertState();
-
-   /* Create necessary tuple slot. */
-   dstslot = MakeSingleTupleTableSlot(RelationGetDescr(newPartRel),
-                                      table_slot_callbacks(newPartRel));
-   ExecStoreAllNullTuple(dstslot);
-
-   foreach(listptr, mergingPartitionsList)
-   {
-       Relation    mergingPartition = (Relation) lfirst(listptr);
-       TupleTableSlot *srcslot;
-       TupleConversionMap *tuple_map;
-       TableScanDesc scan;
-       Snapshot    snapshot;
-
-       /* Create tuple slot for new partition. */
-       srcslot = MakeSingleTupleTableSlot(RelationGetDescr(mergingPartition),
-                                          table_slot_callbacks(mergingPartition));
-
-       /*
-        * Map computing for moving attributes of merged partition to new
-        * partition.
-        */
-       tuple_map = convert_tuples_by_name(RelationGetDescr(mergingPartition),
-                                          RelationGetDescr(newPartRel));
-
-       /* Scan through the rows. */
-       snapshot = RegisterSnapshot(GetLatestSnapshot());
-       scan = table_beginscan(mergingPartition, snapshot, 0, NULL);
-
-       while (table_scan_getnextslot(scan, ForwardScanDirection, srcslot))
-       {
-           TupleTableSlot *insertslot;
-
-           /* Extract data from old tuple. */
-           slot_getallattrs(srcslot);
-
-           if (tuple_map)
-           {
-               /* Need to use map to copy attributes. */
-               insertslot = execute_attr_map_slot(tuple_map->attrMap, srcslot, dstslot);
-           }
-           else
-           {
-               /* Copy attributes directly. */
-               insertslot = dstslot;
-
-               ExecClearTuple(insertslot);
-
-               memcpy(insertslot->tts_values, srcslot->tts_values,
-                      sizeof(Datum) * srcslot->tts_nvalid);
-               memcpy(insertslot->tts_isnull, srcslot->tts_isnull,
-                      sizeof(bool) * srcslot->tts_nvalid);
-
-               ExecStoreVirtualTuple(insertslot);
-           }
-
-           /* Write the tuple out to the new relation. */
-           table_tuple_insert(newPartRel, insertslot, mycid,
-                              ti_options, bistate);
-
-           CHECK_FOR_INTERRUPTS();
-       }
-
-       table_endscan(scan);
-       UnregisterSnapshot(snapshot);
-
-       if (tuple_map)
-           free_conversion_map(tuple_map);
-
-       ExecDropSingleTupleTableSlot(srcslot);
-   }
-
-   ExecDropSingleTupleTableSlot(dstslot);
-   FreeBulkInsertState(bistate);
-
-   table_finish_bulk_insert(newPartRel, ti_options);
-}
-
-/*
- * ALTER TABLE <name> MERGE PARTITIONS <partition-list> INTO <partition-name>
- */
-static void
-ATExecMergePartitions(List **wqueue, AlteredTableInfo *tab, Relation rel,
-                     PartitionCmd *cmd, AlterTableUtilityContext *context)
-{
-   Relation    newPartRel;
-   ListCell   *listptr;
-   List       *mergingPartitionsList = NIL;
-   Oid         defaultPartOid;
-   Oid         namespaceId;
-   Oid         existingRelid;
-
-   /*
-    * Lock all merged partitions, check them and create list with partitions
-    * contexts.
-    */
-   foreach(listptr, cmd->partlist)
-   {
-       RangeVar   *name = (RangeVar *) lfirst(listptr);
-       Relation    mergingPartition;
-
-       /*
-        * We are going to detach and remove this partition: need to use
-        * exclusive lock for preventing DML-queries to the partition.
-        */
-       mergingPartition = table_openrv(name, AccessExclusiveLock);
-
-       /* Store a next merging partition into the list. */
-       mergingPartitionsList = lappend(mergingPartitionsList,
-                                       mergingPartition);
-   }
-
-   /*
-    * Look up the namespace in which we are supposed to create the partition,
-    * check we have permission to create there, lock it against concurrent
-    * drop, and mark stmt->relation as RELPERSISTENCE_TEMP if a temporary
-    * namespace is selected.
-    */
-   cmd->name->relpersistence = rel->rd_rel->relpersistence;
-   namespaceId =
-       RangeVarGetAndCheckCreationNamespace(cmd->name, NoLock, NULL);
-
-   /*
-    * Check if this name is already taken.  This helps us to detect the
-    * situation when one of the merging partitions has the same name as the
-    * new partition.  Otherwise, this would fail later on anyway but catching
-    * this here allows us to emit a nicer error message.
-    */
-   existingRelid = get_relname_relid(cmd->name->relname, namespaceId);
-
-   if (OidIsValid(existingRelid))
-   {
-       Relation    sameNamePartition = NULL;
-
-       foreach_ptr(RelationData, mergingPartition, mergingPartitionsList)
-       {
-           if (RelationGetRelid(mergingPartition) == existingRelid)
-           {
-               sameNamePartition = mergingPartition;
-               break;
-           }
-       }
-
-       if (sameNamePartition)
-       {
-           /*
-            * The new partition has the same name as one of merging
-            * partitions.
-            */
-           char        tmpRelName[NAMEDATALEN];
-
-           /* Generate temporary name. */
-           sprintf(tmpRelName, "merge-%u-%X-tmp", RelationGetRelid(rel), MyProcPid);
-
-           /*
-            * Rename the existing partition with a temporary name, leaving it
-            * free for the new partition.  We don't need to care about this
-            * in the future because we're going to eventually drop the
-            * existing partition anyway.
-            */
-           RenameRelationInternal(RelationGetRelid(sameNamePartition),
-                                  tmpRelName, false, false);
-
-           /*
-            * We must bump the command counter to make the new partition
-            * tuple visible for rename.
-            */
-           CommandCounterIncrement();
-       }
-       else
-       {
-           ereport(ERROR,
-                   (errcode(ERRCODE_DUPLICATE_TABLE),
-                    errmsg("relation \"%s\" already exists", cmd->name->relname)));
-       }
-   }
-
-   /* Detach all merged partitions. */
-   defaultPartOid =
-       get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true));
-   foreach(listptr, mergingPartitionsList)
-   {
-       Relation    mergingPartition = (Relation) lfirst(listptr);
-
-       /* Remove the pg_inherits row first. */
-       RemoveInheritance(mergingPartition, rel, false);
-       /* Do the final part of detaching. */
-       DetachPartitionFinalize(rel, mergingPartition, false, defaultPartOid);
-   }
-
-   /* Create table for new partition, use partitioned table as model. */
-   newPartRel = createPartitionTable(cmd->name, rel, context);
-
-   /* Copy data from merged partitions to new partition. */
-   moveMergedTablesRows(rel, mergingPartitionsList, newPartRel);
-
-   /* Drop the current partitions before attaching the new one. */
-   foreach(listptr, mergingPartitionsList)
-   {
-       ObjectAddress object;
-       Relation    mergingPartition = (Relation) lfirst(listptr);
-
-       /* Get relation id before table_close() call. */
-       object.objectId = RelationGetRelid(mergingPartition);
-       object.classId = RelationRelationId;
-       object.objectSubId = 0;
-
-       /* Keep the lock until commit. */
-       table_close(mergingPartition, NoLock);
-
-       performDeletion(&object, DROP_RESTRICT, 0);
-   }
-   list_free(mergingPartitionsList);
-
-   /*
-    * Attach a new partition to the partitioned table. wqueue = NULL:
-    * verification for each cloned constraint is not needed.
-    */
-   attachPartitionTable(NULL, rel, newPartRel, cmd->bound);
-
-   /* Keep the lock until commit. */
-   table_close(newPartRel, NoLock);
-}
index b7d98eb9f02e7ead63aaa616560c64d0aeaf07fa..84cef57a7078d8839107a4e16e19d28d77d1e828 100644 (file)
@@ -269,7 +269,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
    PartitionElem *partelem;
    PartitionSpec *partspec;
    PartitionBoundSpec *partboundspec;
-   SinglePartitionSpec *singlepartspec;
    RoleSpec   *rolespec;
    PublicationObjSpec *publicationobjectspec;
    struct SelectLimit *selectlimit;
@@ -646,8 +645,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <partelem>   part_elem
 %type <list>       part_params
 %type <partboundspec> PartitionBoundSpec
-%type <singlepartspec> SinglePartitionSpec
-%type <list>       partitions_list
 %type <list>       hash_partbound
 %type <defelt>     hash_partbound_elem
 
@@ -763,7 +760,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
    ORDER ORDINALITY OTHERS OUT_P OUTER_P
    OVER OVERLAPS OVERLAY OVERRIDING OWNED OWNER
 
-   PARALLEL PARAMETER PARSER PARTIAL PARTITION PARTITIONS PASSING PASSWORD PATH
+   PARALLEL PARAMETER PARSER PARTIAL PARTITION PASSING PASSWORD PATH
    PLACING PLAN PLANS POLICY
    POSITION PRECEDING PRECISION PRESERVE PREPARE PREPARED PRIMARY
    PRIOR PRIVILEGES PROCEDURAL PROCEDURE PROCEDURES PROGRAM PUBLICATION
@@ -778,7 +775,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
    SAVEPOINT SCALAR SCHEMA SCHEMAS SCROLL SEARCH SECOND_P SECURITY SELECT
    SEQUENCE SEQUENCES
    SERIALIZABLE SERVER SESSION SESSION_USER SET SETS SETOF SHARE SHOW
-   SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SPLIT SOURCE SQL_P STABLE STANDALONE_P
+   SIMILAR SIMPLE SKIP SMALLINT SNAPSHOT SOME SOURCE SQL_P STABLE STANDALONE_P
    START STATEMENT STATISTICS STDIN STDOUT STORAGE STORED STRICT_P STRING_P STRIP_P
    SUBSCRIPTION SUBSTRING SUPPORT SYMMETRIC SYSID SYSTEM_P SYSTEM_USER
 
@@ -2311,23 +2308,6 @@ alter_table_cmds:
            | alter_table_cmds ',' alter_table_cmd  { $$ = lappend($1, $3); }
        ;
 
-partitions_list:
-           SinglePartitionSpec                         { $$ = list_make1($1); }
-           | partitions_list ',' SinglePartitionSpec   { $$ = lappend($1, $3); }
-       ;
-
-SinglePartitionSpec:
-           PARTITION qualified_name PartitionBoundSpec
-               {
-                   SinglePartitionSpec *n = makeNode(SinglePartitionSpec);
-
-                   n->name = $2;
-                   n->bound = $3;
-
-                   $$ = n;
-               }
-       ;
-
 partition_cmd:
            /* ALTER TABLE <name> ATTACH PARTITION <table_name> FOR VALUES */
            ATTACH PARTITION qualified_name PartitionBoundSpec
@@ -2338,7 +2318,6 @@ partition_cmd:
                    n->subtype = AT_AttachPartition;
                    cmd->name = $3;
                    cmd->bound = $4;
-                   cmd->partlist = NULL;
                    cmd->concurrent = false;
                    n->def = (Node *) cmd;
 
@@ -2353,7 +2332,6 @@ partition_cmd:
                    n->subtype = AT_DetachPartition;
                    cmd->name = $3;
                    cmd->bound = NULL;
-                   cmd->partlist = NULL;
                    cmd->concurrent = $4;
                    n->def = (Node *) cmd;
 
@@ -2367,35 +2345,6 @@ partition_cmd:
                    n->subtype = AT_DetachPartitionFinalize;
                    cmd->name = $3;
                    cmd->bound = NULL;
-                   cmd->partlist = NULL;
-                   cmd->concurrent = false;
-                   n->def = (Node *) cmd;
-                   $$ = (Node *) n;
-               }
-           /* ALTER TABLE <name> SPLIT PARTITION <partition_name> INTO () */
-           | SPLIT PARTITION qualified_name INTO '(' partitions_list ')'
-               {
-                   AlterTableCmd *n = makeNode(AlterTableCmd);
-                   PartitionCmd *cmd = makeNode(PartitionCmd);
-
-                   n->subtype = AT_SplitPartition;
-                   cmd->name = $3;
-                   cmd->bound = NULL;
-                   cmd->partlist = $6;
-                   cmd->concurrent = false;
-                   n->def = (Node *) cmd;
-                   $$ = (Node *) n;
-               }
-           /* ALTER TABLE <name> MERGE PARTITIONS () INTO <partition_name> */
-           | MERGE PARTITIONS '(' qualified_name_list ')' INTO qualified_name
-               {
-                   AlterTableCmd *n = makeNode(AlterTableCmd);
-                   PartitionCmd *cmd = makeNode(PartitionCmd);
-
-                   n->subtype = AT_MergePartitions;
-                   cmd->name = $7;
-                   cmd->bound = NULL;
-                   cmd->partlist = $4;
                    cmd->concurrent = false;
                    n->def = (Node *) cmd;
                    $$ = (Node *) n;
@@ -2412,7 +2361,6 @@ index_partition_cmd:
                    n->subtype = AT_AttachPartition;
                    cmd->name = $3;
                    cmd->bound = NULL;
-                   cmd->partlist = NULL;
                    cmd->concurrent = false;
                    n->def = (Node *) cmd;
 
@@ -4138,7 +4086,6 @@ TableLikeClause:
                    n->relation = $2;
                    n->options = $3;
                    n->relationOid = InvalidOid;
-                   n->newRelationOid = InvalidOid;
                    $$ = (Node *) n;
                }
        ;
@@ -17744,7 +17691,6 @@ unreserved_keyword:
            | PARSER
            | PARTIAL
            | PARTITION
-           | PARTITIONS
            | PASSING
            | PASSWORD
            | PATH
@@ -17812,7 +17758,6 @@ unreserved_keyword:
            | SKIP
            | SNAPSHOT
            | SOURCE
-           | SPLIT
            | SQL_P
            | STABLE
            | STANDALONE_P
@@ -18369,7 +18314,6 @@ bare_label_keyword:
            | PARSER
            | PARTIAL
            | PARTITION
-           | PARTITIONS
            | PASSING
            | PASSWORD
            | PATH
@@ -18449,7 +18393,6 @@ bare_label_keyword:
            | SNAPSHOT
            | SOME
            | SOURCE
-           | SPLIT
            | SQL_P
            | STABLE
            | STANDALONE_P
index d5c2b2ff0b0b3fbd6aa05e86d79c7e3b019bd1e9..79cad4ab30ca8caf9b202664f4d2987d5add9213 100644 (file)
@@ -32,7 +32,6 @@
 #include "catalog/heap.h"
 #include "catalog/index.h"
 #include "catalog/namespace.h"
-#include "catalog/partition.h"
 #include "catalog/pg_am.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_constraint.h"
@@ -59,8 +58,6 @@
 #include "parser/parse_type.h"
 #include "parser/parse_utilcmd.h"
 #include "parser/parser.h"
-#include "partitioning/partdesc.h"
-#include "partitioning/partbounds.h"
 #include "rewrite/rewriteManip.h"
 #include "utils/acl.h"
 #include "utils/builtins.h"
@@ -136,7 +133,7 @@ static void transformConstraintAttrs(CreateStmtContext *cxt,
                                     List *constraintList);
 static void transformColumnType(CreateStmtContext *cxt, ColumnDef *column);
 static void setSchemaName(const char *context_schema, char **stmt_schema_name);
-static void transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound);
+static void transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd);
 static List *transformPartitionRangeBounds(ParseState *pstate, List *blist,
                                           Relation parent);
 static void validateInfiniteBounds(ParseState *pstate, List *blist);
@@ -3232,160 +3229,6 @@ transformRuleStmt(RuleStmt *stmt, const char *queryString,
 }
 
 
-/*
- * checkPartition
- *     Check that partRelOid is an oid of partition of the parent table rel
- */
-static void
-checkPartition(Relation rel, Oid partRelOid)
-{
-   Relation    partRel;
-
-   partRel = relation_open(partRelOid, AccessShareLock);
-
-   if (partRel->rd_rel->relkind != RELKIND_RELATION)
-       ereport(ERROR,
-               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                errmsg("\"%s\" is not a table",
-                       RelationGetRelationName(partRel))));
-
-   if (!partRel->rd_rel->relispartition)
-       ereport(ERROR,
-               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
-                errmsg("\"%s\" is not a partition",
-                       RelationGetRelationName(partRel))));
-
-   if (get_partition_parent(partRelOid, false) != RelationGetRelid(rel))
-       ereport(ERROR,
-               (errcode(ERRCODE_UNDEFINED_TABLE),
-                errmsg("relation \"%s\" is not a partition of relation \"%s\"",
-                       RelationGetRelationName(partRel),
-                       RelationGetRelationName(rel))));
-
-   /* Permissions checks */
-   if (!object_ownercheck(RelationRelationId, RelationGetRelid(partRel), GetUserId()))
-       aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(partRel->rd_rel->relkind),
-                      RelationGetRelationName(partRel));
-
-   relation_close(partRel, AccessShareLock);
-}
-
-/*
- * transformPartitionCmdForSplit
- *     Analyze the ALTER TABLE ... SPLIT PARTITION command
- *
- * For each new partition sps->bound is set to the transformed value of bound.
- * Does checks for bounds of new partitions.
- */
-static void
-transformPartitionCmdForSplit(CreateStmtContext *cxt, PartitionCmd *partcmd)
-{
-   Relation    parent = cxt->rel;
-   Oid         splitPartOid;
-   ListCell   *listptr;
-
-   if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("\"%s\" is not a partitioned table", RelationGetRelationName(parent))));
-
-   /* Transform partition bounds for all partitions in the list: */
-   foreach(listptr, partcmd->partlist)
-   {
-       SinglePartitionSpec *sps = (SinglePartitionSpec *) lfirst(listptr);
-
-       cxt->partbound = NULL;
-       transformPartitionCmd(cxt, sps->bound);
-       /* Assign transformed value of the partition bound. */
-       sps->bound = cxt->partbound;
-   }
-
-   splitPartOid = RangeVarGetRelid(partcmd->name, NoLock, false);
-
-   checkPartition(parent, splitPartOid);
-
-   /* Then we should check partitions with transformed bounds. */
-   check_partitions_for_split(parent, splitPartOid, partcmd->name, partcmd->partlist, cxt->pstate);
-}
-
-
-/*
- * transformPartitionCmdForMerge
- *     Analyze the ALTER TABLE ... MERGE PARTITIONS command
- *
- * Does simple checks for merged partitions. Calculates bound of resulting
- * partition.
- */
-static void
-transformPartitionCmdForMerge(CreateStmtContext *cxt, PartitionCmd *partcmd)
-{
-   Oid         defaultPartOid;
-   Oid         partOid;
-   Relation    parent = cxt->rel;
-   PartitionKey key;
-   char        strategy;
-   ListCell   *listptr,
-              *listptr2;
-   bool        isDefaultPart = false;
-   List       *partOids = NIL;
-
-   if (parent->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("\"%s\" is not a partitioned table", RelationGetRelationName(parent))));
-
-   key = RelationGetPartitionKey(parent);
-   strategy = get_partition_strategy(key);
-
-   if (strategy == PARTITION_STRATEGY_HASH)
-       ereport(ERROR,
-               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                errmsg("partition of hash-partitioned table cannot be merged")));
-
-   /* Is current partition a DEFAULT partition? */
-   defaultPartOid = get_default_oid_from_partdesc(
-                                                  RelationGetPartitionDesc(parent, true));
-
-   foreach(listptr, partcmd->partlist)
-   {
-       RangeVar   *name = (RangeVar *) lfirst(listptr);
-
-       /* Partitions in the list should have different names. */
-       for_each_cell(listptr2, partcmd->partlist, lnext(partcmd->partlist, listptr))
-       {
-           RangeVar   *name2 = (RangeVar *) lfirst(listptr2);
-
-           if (equal(name, name2))
-               ereport(ERROR,
-                       (errcode(ERRCODE_DUPLICATE_TABLE),
-                        errmsg("partition with name \"%s\" is already used", name->relname)),
-                       parser_errposition(cxt->pstate, name2->location));
-       }
-
-       /* Search DEFAULT partition in the list. */
-       partOid = RangeVarGetRelid(name, NoLock, false);
-       if (partOid == defaultPartOid)
-           isDefaultPart = true;
-
-       checkPartition(parent, partOid);
-
-       partOids = lappend_oid(partOids, partOid);
-   }
-
-   /* Allocate bound of resulting partition. */
-   Assert(partcmd->bound == NULL);
-   partcmd->bound = makeNode(PartitionBoundSpec);
-
-   /* Fill partition bound. */
-   partcmd->bound->strategy = strategy;
-   partcmd->bound->location = -1;
-   partcmd->bound->is_default = isDefaultPart;
-   if (!isDefaultPart)
-       calculate_partition_bound_for_merge(parent, partcmd->partlist,
-                                           partOids, partcmd->bound,
-                                           cxt->pstate);
-}
-
 /*
  * transformAlterTableStmt -
  *     parse analysis for ALTER TABLE
@@ -3654,7 +3497,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
                {
                    PartitionCmd *partcmd = (PartitionCmd *) cmd->def;
 
-                   transformPartitionCmd(&cxt, partcmd->bound);
+                   transformPartitionCmd(&cxt, partcmd);
                    /* assign transformed value of the partition bound */
                    partcmd->bound = cxt.partbound;
                }
@@ -3662,24 +3505,6 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
                newcmds = lappend(newcmds, cmd);
                break;
 
-           case AT_SplitPartition:
-           case AT_MergePartitions:
-               {
-                   PartitionCmd *partcmd = (PartitionCmd *) cmd->def;
-
-                   if (list_length(partcmd->partlist) < 2)
-                       ereport(ERROR,
-                               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                                errmsg("list of new partitions should contain at least two items")));
-
-                   if (cmd->subtype == AT_SplitPartition)
-                       transformPartitionCmdForSplit(&cxt, partcmd);
-                   else
-                       transformPartitionCmdForMerge(&cxt, partcmd);
-                   newcmds = lappend(newcmds, cmd);
-                   break;
-               }
-
            default:
 
                /*
@@ -4070,13 +3895,13 @@ setSchemaName(const char *context_schema, char **stmt_schema_name)
 
 /*
  * transformPartitionCmd
- *     Analyze the ATTACH/DETACH/SPLIT PARTITION command
+ *     Analyze the ATTACH/DETACH PARTITION command
  *
- * In case of the ATTACH/SPLIT PARTITION command, cxt->partbound is set to the
- * transformed value of bound.
+ * In case of the ATTACH PARTITION command, cxt->partbound is set to the
+ * transformed value of cmd->bound.
  */
 static void
-transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound)
+transformPartitionCmd(CreateStmtContext *cxt, PartitionCmd *cmd)
 {
    Relation    parentRel = cxt->rel;
 
@@ -4085,9 +3910,9 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound)
        case RELKIND_PARTITIONED_TABLE:
            /* transform the partition bound, if any */
            Assert(RelationGetPartitionKey(parentRel) != NULL);
-           if (bound != NULL)
+           if (cmd->bound != NULL)
                cxt->partbound = transformPartitionBound(cxt->pstate, parentRel,
-                                                        bound);
+                                                        cmd->bound);
            break;
        case RELKIND_PARTITIONED_INDEX:
 
@@ -4095,7 +3920,7 @@ transformPartitionCmd(CreateStmtContext *cxt, PartitionBoundSpec *bound)
             * A partitioned index cannot have a partition bound set.  ALTER
             * INDEX prevents that with its grammar, but not ALTER TABLE.
             */
-           if (bound != NULL)
+           if (cmd->bound != NULL)
                ereport(ERROR,
                        (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
                         errmsg("\"%s\" is not a partitioned table",
index 4eda59767ce7b770406dd4d944a8a57063b5aa57..c28639d2e3f4f91ac1f9d575d78ef08402549d24 100644 (file)
@@ -3214,9 +3214,8 @@ check_new_partition_bound(char *relname, Relation parent,
                        PartitionRangeDatum *datum;
 
                        /*
-                        * Point to problematic key in the list of lower
-                        * datums; if we have equality, point to the first
-                        * one.
+                        * Point to problematic key in the lower datums list;
+                        * if we have equality, point to the first one.
                         */
                        datum = cmpval == 0 ? linitial(spec->lowerdatums) :
                            list_nth(spec->lowerdatums, abs(cmpval) - 1);
@@ -4978,899 +4977,3 @@ satisfies_hash_partition(PG_FUNCTION_ARGS)
 
    PG_RETURN_BOOL(rowHash % modulus == remainder);
 }
-
-/*
- * check_two_partitions_bounds_range
- *
- * (function for BY RANGE partitioning)
- *
- * This is a helper function for check_partitions_for_split() and
- * calculate_partition_bound_for_merge().
- * This function compares upper bound of first_bound and lower bound of
- * second_bound. These bounds should be equal except when
- * "defaultPart == true" (this means that one of split partitions is DEFAULT).
- * In this case upper bound of first_bound can be less than lower bound of
- * second_bound because space between these bounds will be included in
- * DEFAULT partition.
- *
- * parent:         partitioned table
- * first_name:     name of first partition
- * first_bound:        bound of first partition
- * second_name:        name of second partition
- * second_bound:   bound of second partition
- * defaultPart:        true if one of split partitions is DEFAULT
- * pstate:         pointer to ParseState struct for determining error position
- */
-static void
-check_two_partitions_bounds_range(Relation parent,
-                                 RangeVar *first_name,
-                                 PartitionBoundSpec *first_bound,
-                                 RangeVar *second_name,
-                                 PartitionBoundSpec *second_bound,
-                                 bool defaultPart,
-                                 ParseState *pstate)
-{
-   PartitionKey key = RelationGetPartitionKey(parent);
-   PartitionRangeBound *first_upper;
-   PartitionRangeBound *second_lower;
-   int         cmpval;
-
-   Assert(key->strategy == PARTITION_STRATEGY_RANGE);
-
-   first_upper = make_one_partition_rbound(key, -1, first_bound->upperdatums, false);
-   second_lower = make_one_partition_rbound(key, -1, second_bound->lowerdatums, true);
-
-   /*
-    * lower1=false (the second to last argument) for correct comparison of
-    * lower and upper bounds.
-    */
-   cmpval = partition_rbound_cmp(key->partnatts,
-                                 key->partsupfunc,
-                                 key->partcollation,
-                                 second_lower->datums, second_lower->kind,
-                                 false, first_upper);
-   if ((!defaultPart && cmpval) || (defaultPart && cmpval < 0))
-   {
-       PartitionRangeDatum *datum = linitial(second_bound->lowerdatums);
-
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("lower bound of partition \"%s\" conflicts with upper bound of previous partition \"%s\"",
-                       second_name->relname, first_name->relname),
-                parser_errposition(pstate, datum->location)));
-   }
-}
-
-/*
- * check_partitions_not_overlap_list
- *
- * (function for BY LIST partitioning)
- *
- * This is a helper function for check_partitions_for_split().
- * Checks that the values of the new partitions do not overlap.
- *
- * parent: partitioned table
- * parts:  array of SinglePartitionSpec structs with info about split partitions
- * nparts: size of array "parts"
- */
-static void
-check_partitions_not_overlap_list(Relation parent,
-                                 SinglePartitionSpec **parts,
-                                 int nparts,
-                                 ParseState *pstate)
-{
-   PartitionKey key PG_USED_FOR_ASSERTS_ONLY = RelationGetPartitionKey(parent);
-   int         overlap_location = -1;
-   int         i,
-               j;
-   SinglePartitionSpec *sps1,
-              *sps2;
-   List       *overlap;
-
-   Assert(key->strategy == PARTITION_STRATEGY_LIST);
-
-   for (i = 0; i < nparts; i++)
-   {
-       sps1 = parts[i];
-
-       for (j = i + 1; j < nparts; j++)
-       {
-           sps2 = parts[j];
-
-           /*
-            * Calculate intersection between values of two partitions.
-            */
-           overlap = list_intersection(sps1->bound->listdatums,
-                                       sps2->bound->listdatums);
-           if (list_length(overlap) > 0)
-           {
-               Const      *val = (Const *) lfirst(list_head(overlap));
-
-               overlap_location = val->location;
-               ereport(ERROR,
-                       (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                        errmsg("new partition \"%s\" would overlap with another new partition \"%s\"",
-                               sps1->name->relname, sps2->name->relname),
-                        parser_errposition(pstate, overlap_location)));
-           }
-       }
-   }
-}
-
-/*
- * get_partition_bound_spec
- *
- * Returns description of partition with Oid "partOid" and name "name".
- *
- * partOid:    partition Oid
- * name:   partition name
- */
-static PartitionBoundSpec *
-get_partition_bound_spec(Oid partOid, RangeVar *name)
-{
-   HeapTuple   tuple;
-   Datum       datum;
-   bool        isnull;
-   PartitionBoundSpec *boundspec = NULL;
-
-   /* Try fetching the tuple from the catcache, for speed. */
-   tuple = SearchSysCache1(RELOID, partOid);
-   if (!HeapTupleIsValid(tuple))
-       elog(ERROR, "cache lookup failed for relation \"%s\"",
-            name->relname);
-
-   datum = SysCacheGetAttr(RELOID, tuple,
-                           Anum_pg_class_relpartbound,
-                           &isnull);
-   if (isnull)
-       elog(ERROR, "partition bound for relation \"%s\" is null",
-            name->relname);
-
-   boundspec = stringToNode(TextDatumGetCString(datum));
-
-   if (!IsA(boundspec, PartitionBoundSpec))
-       elog(ERROR, "expected PartitionBoundSpec for relation \"%s\"",
-            name->relname);
-
-   ReleaseSysCache(tuple);
-   return boundspec;
-}
-
-/*
- * check_partition_bounds_for_split_range
- *
- * (function for BY RANGE partitioning)
- *
- * Checks that bounds of new partition "spec" are inside bounds of split
- * partition (with Oid splitPartOid). If first=true (this means that "spec" is
- * the first of new partitions) then lower bound of "spec" should be equal (or
- * greater than or equal in case defaultPart=true) to lower bound of split
- * partition. If last=true (this means that "spec" is the last of new
- * partitions) then upper bound of "spec" should be equal (or less than or
- * equal in case defaultPart=true) to upper bound of split partition.
- *
- * parent:         partitioned table
- * relname:            name of the new partition
- * spec:           bounds specification of the new partition
- * splitPartOid:   split partition Oid
- * splitPartName:  split partition name
- * first:          true in case new partition "spec" is first of new partitions
- * last:           true in case new partition "spec" is last of new partitions
- * defaultPart:        true in case partitioned table has DEFAULT partition
- * pstate:         pointer to ParseState struct for determine error position
- */
-static void
-check_partition_bounds_for_split_range(Relation parent,
-                                      char *relname,
-                                      PartitionBoundSpec *spec,
-                                      Oid splitPartOid,
-                                      RangeVar *splitPartName,
-                                      bool first,
-                                      bool last,
-                                      bool defaultPart,
-                                      ParseState *pstate)
-{
-   PartitionKey key = RelationGetPartitionKey(parent);
-   PartitionRangeBound *lower,
-              *upper;
-   int         cmpval;
-
-   Assert(key->strategy == PARTITION_STRATEGY_RANGE);
-   Assert(spec->strategy == PARTITION_STRATEGY_RANGE);
-
-   lower = make_one_partition_rbound(key, -1, spec->lowerdatums, true);
-   upper = make_one_partition_rbound(key, -1, spec->upperdatums, false);
-
-   /*
-    * First check if the resulting range would be empty with specified lower
-    * and upper bounds.  partition_rbound_cmp cannot return zero here, since
-    * the lower-bound flags are different.
-    */
-   cmpval = partition_rbound_cmp(key->partnatts,
-                                 key->partsupfunc,
-                                 key->partcollation,
-                                 lower->datums, lower->kind,
-                                 true, upper);
-   Assert(cmpval != 0);
-   if (cmpval > 0)
-   {
-       /* Point to problematic key in the lower datums list. */
-       PartitionRangeDatum *datum = list_nth(spec->lowerdatums, cmpval - 1);
-
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("empty range bound specified for partition \"%s\"",
-                       relname),
-                errdetail("Specified lower bound %s is greater than or equal to upper bound %s.",
-                          get_range_partbound_string(spec->lowerdatums),
-                          get_range_partbound_string(spec->upperdatums)),
-                parser_errposition(pstate, datum->location)));
-   }
-
-   /* Need to check first and last partitions (from set of new partitions) */
-   if (first || last)
-   {
-       PartitionBoundSpec *split_spec = get_partition_bound_spec(splitPartOid, splitPartName);
-       PartitionRangeDatum *datum;
-
-       if (first)
-       {
-           PartitionRangeBound *split_lower;
-
-           split_lower = make_one_partition_rbound(key, -1, split_spec->lowerdatums, true);
-
-           cmpval = partition_rbound_cmp(key->partnatts,
-                                         key->partsupfunc,
-                                         key->partcollation,
-                                         lower->datums, lower->kind,
-                                         true, split_lower);
-
-           /*
-            * Lower bound of "spec" should be equal (or greater than or equal
-            * in case defaultPart=true) to lower bound of split partition.
-            */
-           if (!defaultPart)
-           {
-               if (cmpval != 0)
-               {
-                   datum = list_nth(spec->lowerdatums, abs(cmpval) - 1);
-                   ereport(ERROR,
-                           (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                            errmsg("lower bound of partition \"%s\" is not equal to lower bound of split partition",
-                                   relname),
-                            parser_errposition(pstate, datum->location)));
-               }
-           }
-           else
-           {
-               if (cmpval < 0)
-               {
-                   datum = list_nth(spec->lowerdatums, abs(cmpval) - 1);
-                   ereport(ERROR,
-                           (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                            errmsg("lower bound of partition \"%s\" is less than lower bound of split partition",
-                                   relname),
-                            parser_errposition(pstate, datum->location)));
-               }
-           }
-       }
-       else
-       {
-           PartitionRangeBound *split_upper;
-
-           split_upper = make_one_partition_rbound(key, -1, split_spec->upperdatums, false);
-
-           cmpval = partition_rbound_cmp(key->partnatts,
-                                         key->partsupfunc,
-                                         key->partcollation,
-                                         upper->datums, upper->kind,
-                                         false, split_upper);
-
-           /*
-            * Upper bound of "spec" should be equal (or less than or equal in
-            * case defaultPart=true) to upper bound of split partition.
-            */
-           if (!defaultPart)
-           {
-               if (cmpval != 0)
-               {
-                   datum = list_nth(spec->upperdatums, abs(cmpval) - 1);
-                   ereport(ERROR,
-                           (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                            errmsg("upper bound of partition \"%s\" is not equal to upper bound of split partition",
-                                   relname),
-                            parser_errposition(pstate, datum->location)));
-               }
-           }
-           else
-           {
-               if (cmpval > 0)
-               {
-                   datum = list_nth(spec->upperdatums, abs(cmpval) - 1);
-                   ereport(ERROR,
-                           (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                            errmsg("upper bound of partition \"%s\" is greater than upper bound of split partition",
-                                   relname),
-                            parser_errposition(pstate, datum->location)));
-               }
-           }
-       }
-   }
-}
-
-/*
- * check_partition_bounds_for_split_list
- *
- * (function for BY LIST partitioning)
- *
- * Checks that bounds of new partition are inside bounds of split partition
- * (with Oid splitPartOid).
- *
- * parent:         partitioned table
- * relname:            name of the new partition
- * spec:           bounds specification of the new partition
- * splitPartOid:   split partition Oid
- * pstate:         pointer to ParseState struct for determine error position
- */
-static void
-check_partition_bounds_for_split_list(Relation parent, char *relname,
-                                     PartitionBoundSpec *spec,
-                                     Oid splitPartOid,
-                                     ParseState *pstate)
-{
-   PartitionKey key = RelationGetPartitionKey(parent);
-   PartitionDesc partdesc = RelationGetPartitionDesc(parent, false);
-   PartitionBoundInfo boundinfo = partdesc->boundinfo;
-   int         with = -1;
-   bool        overlap = false;
-   int         overlap_location = -1;
-   ListCell   *cell;
-
-   Assert(key->strategy == PARTITION_STRATEGY_LIST);
-   Assert(spec->strategy == PARTITION_STRATEGY_LIST);
-   Assert(boundinfo && boundinfo->strategy == PARTITION_STRATEGY_LIST);
-
-   /*
-    * Search each value of new partition "spec" in existing partitions. All
-    * of them should be in split partition (with Oid splitPartOid).
-    */
-   foreach(cell, spec->listdatums)
-   {
-       Const      *val = lfirst_node(Const, cell);
-
-       overlap_location = val->location;
-       if (!val->constisnull)
-       {
-           int         offset;
-           bool        equal;
-
-           offset = partition_list_bsearch(&key->partsupfunc[0],
-                                           key->partcollation,
-                                           boundinfo,
-                                           val->constvalue,
-                                           &equal);
-           if (offset >= 0 && equal)
-           {
-               with = boundinfo->indexes[offset];
-               if (partdesc->oids[with] != splitPartOid)
-               {
-                   overlap = true;
-                   break;
-               }
-           }
-           else
-               ereport(ERROR,
-                       (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                        errmsg("new partition \"%s\" cannot have this value because split partition does not have",
-                               relname),
-                        parser_errposition(pstate, overlap_location)));
-       }
-       else if (partition_bound_accepts_nulls(boundinfo))
-       {
-           with = boundinfo->null_index;
-           if (partdesc->oids[with] != splitPartOid)
-           {
-               overlap = true;
-               break;
-           }
-       }
-       else
-           ereport(ERROR,
-                   (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                    errmsg("new partition \"%s\" cannot have NULL value because split partition does not have",
-                           relname),
-                    parser_errposition(pstate, overlap_location)));
-   }
-
-   if (overlap)
-   {
-       Assert(with >= 0);
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("new partition \"%s\" would overlap with another (not split) partition \"%s\"",
-                       relname, get_rel_name(partdesc->oids[with])),
-                parser_errposition(pstate, overlap_location)));
-   }
-}
-
-/*
- * find_value_in_new_partitions_list
- *
- * (function for BY LIST partitioning)
- *
- * Function returns true in case any of new partitions contains value "value".
- *
- * partsupfunc:        information about comparison function associated with the partition key
- * partcollation:  partitioning collation
- * parts:          pointer to array with new partitions descriptions
- * nparts:         number of new partitions
- * value:          the value that we are looking for
- * isnull:         true if the value that we are looking for is NULL
- */
-static bool
-find_value_in_new_partitions_list(FmgrInfo *partsupfunc,
-                                 Oid *partcollation,
-                                 SinglePartitionSpec **parts,
-                                 int nparts,
-                                 Datum value,
-                                 bool isnull)
-{
-   ListCell   *valptr;
-   int         i;
-
-   for (i = 0; i < nparts; i++)
-   {
-       SinglePartitionSpec *sps = parts[i];
-
-       foreach(valptr, sps->bound->listdatums)
-       {
-           Const      *val = lfirst_node(Const, valptr);
-
-           if (isnull && val->constisnull)
-               return true;
-
-           if (!isnull && !val->constisnull)
-           {
-               if (DatumGetInt32(FunctionCall2Coll(&partsupfunc[0],
-                                                   partcollation[0],
-                                                   val->constvalue,
-                                                   value)) == 0)
-                   return true;
-           }
-       }
-   }
-   return false;
-}
-
-/*
- * check_parent_values_in_new_partitions
- *
- * (function for BY LIST partitioning)
- *
- * Checks that all values of split partition (with Oid partOid) contains in new
- * partitions.
- *
- * parent: partitioned table
- * partOid:    split partition Oid
- * parts:  pointer to array with new partitions descriptions
- * nparts: number of new partitions
- * pstate: pointer to ParseState struct for determine error position
- */
-static void
-check_parent_values_in_new_partitions(Relation parent,
-                                     Oid partOid,
-                                     SinglePartitionSpec **parts,
-                                     int nparts,
-                                     ParseState *pstate)
-{
-   PartitionKey key = RelationGetPartitionKey(parent);
-   PartitionDesc partdesc = RelationGetPartitionDesc(parent, false);
-   PartitionBoundInfo boundinfo = partdesc->boundinfo;
-   int         i;
-   bool        found = true;
-   bool        searchNull = false;
-   Datum       datum = PointerGetDatum(NULL);
-
-   Assert(key->strategy == PARTITION_STRATEGY_LIST);
-
-   /*
-    * Special processing for NULL value. Search NULL value if the split
-    * partition (partOid) contains it.
-    */
-   if (partition_bound_accepts_nulls(boundinfo) &&
-       partdesc->oids[boundinfo->null_index] == partOid)
-   {
-       if (!find_value_in_new_partitions_list(&key->partsupfunc[0],
-                                              key->partcollation, parts, nparts, datum, true))
-       {
-           found = false;
-           searchNull = true;
-       }
-   }
-
-   /*
-    * Search all values of split partition with partOid in PartitionDesc of
-    * partitioned table.
-    */
-   for (i = 0; i < boundinfo->ndatums; i++)
-   {
-       if (partdesc->oids[boundinfo->indexes[i]] == partOid)
-       {
-           /* We found value that split partition contains. */
-           datum = boundinfo->datums[i][0];
-           if (!find_value_in_new_partitions_list(&key->partsupfunc[0],
-                                                  key->partcollation, parts, nparts, datum, false))
-           {
-               found = false;
-               break;
-           }
-       }
-   }
-
-   if (!found)
-   {
-       Const      *notFoundVal;
-
-       if (!searchNull)
-
-           /*
-            * Make Const for getting string representation of not found
-            * value.
-            */
-           notFoundVal = makeConst(key->parttypid[0],
-                                   key->parttypmod[0],
-                                   key->parttypcoll[0],
-                                   key->parttyplen[0],
-                                   datum,
-                                   false,  /* isnull */
-                                   key->parttypbyval[0]);
-
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("new partitions do not have value %s but split partition does",
-                       searchNull ? "NULL" : get_list_partvalue_string(notFoundVal))));
-   }
-}
-
-/*
- * check_partitions_for_split
- *
- * Checks new partitions for SPLIT PARTITIONS command:
- * 1. DEFAULT partition should be one.
- * 2. New partitions should have different names
- *    (with existing partitions too).
- * 3. Bounds of new partitions should not overlap with new and existing
- *    partitions.
- * 4. In case split partition is DEFAULT partition, one of new partitions
- *    should be DEFAULT.
- * 5. In case new partitions or existing partitions contains DEFAULT
- *    partition, new partitions can have any bounds inside split
- *    partition bound (can be spaces between partitions bounds).
- * 6. In case partitioned table does not have DEFAULT partition, DEFAULT
- *    partition can be defined as one of new partition.
- * 7. In case new partitions not contains DEFAULT partition and
- *    partitioned table does not have DEFAULT partition the following
- *    should be true: sum bounds of new partitions should be equal
- *    to bound of split partition.
- *
- * parent:         partitioned table
- * splitPartOid:   split partition Oid
- * splitPartName:  split partition name
- * list:           list of new partitions
- * pstate:         pointer to ParseState struct for determine error position
- */
-void
-check_partitions_for_split(Relation parent,
-                          Oid splitPartOid,
-                          RangeVar *splitPartName,
-                          List *partlist,
-                          ParseState *pstate)
-{
-   PartitionKey key;
-   char        strategy;
-   Oid         defaultPartOid;
-   bool        isSplitPartDefault;
-   bool        existsDefaultPart;
-   ListCell   *listptr;
-   int         default_index = -1;
-   int         i,
-               j;
-   SinglePartitionSpec **new_parts;
-   SinglePartitionSpec *spsPrev = NULL;
-   int         nparts = 0;
-
-   key = RelationGetPartitionKey(parent);
-   strategy = get_partition_strategy(key);
-
-   switch (strategy)
-   {
-       case PARTITION_STRATEGY_LIST:
-       case PARTITION_STRATEGY_RANGE:
-           {
-               /*
-                * Make array new_parts with new partitions except DEFAULT
-                * partition.
-                */
-               new_parts = (SinglePartitionSpec **)
-                   palloc0(list_length(partlist) * sizeof(SinglePartitionSpec *));
-               i = 0;
-               foreach(listptr, partlist)
-               {
-                   SinglePartitionSpec *sps =
-                       (SinglePartitionSpec *) lfirst(listptr);
-
-                   if (sps->bound->is_default)
-                   {
-                       if (default_index >= 0)
-                           ereport(ERROR,
-                                   (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                                    errmsg("DEFAULT partition should be one")),
-                                   parser_errposition(pstate, sps->name->location));
-                       default_index = i;
-                   }
-                   else
-                   {
-                       new_parts[nparts++] = sps;
-                   }
-                   i++;
-               }
-           }
-           break;
-
-       case PARTITION_STRATEGY_HASH:
-           ereport(ERROR,
-                   (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                    errmsg("partition of hash-partitioned table cannot be split")));
-           break;
-
-       default:
-           elog(ERROR, "unexpected partition strategy: %d",
-                (int) key->strategy);
-           break;
-   }
-
-   if (strategy == PARTITION_STRATEGY_RANGE)
-   {
-       PartitionRangeBound **lower_bounds;
-       SinglePartitionSpec **tmp_new_parts;
-
-       /*
-        * For simplify check for ranges of new partitions need to sort all
-        * partitions in ascending order of them bounds (we compare upper
-        * bound only).
-        */
-       lower_bounds = (PartitionRangeBound **)
-           palloc0(nparts * sizeof(PartitionRangeBound *));
-
-       /* Create array of lower bounds. */
-       for (i = 0; i < nparts; i++)
-       {
-           lower_bounds[i] = make_one_partition_rbound(key, i,
-                                                       new_parts[i]->bound->lowerdatums, true);
-       }
-
-       /* Sort array of lower bounds. */
-       qsort_arg(lower_bounds, nparts, sizeof(PartitionRangeBound *),
-                 qsort_partition_rbound_cmp, (void *) key);
-
-       /* Reorder array of partitions. */
-       tmp_new_parts = new_parts;
-       new_parts = (SinglePartitionSpec **)
-           palloc0(nparts * sizeof(SinglePartitionSpec *));
-       for (i = 0; i < nparts; i++)
-           new_parts[i] = tmp_new_parts[lower_bounds[i]->index];
-
-       pfree(tmp_new_parts);
-       pfree(lower_bounds);
-   }
-
-   defaultPartOid =
-       get_default_oid_from_partdesc(RelationGetPartitionDesc(parent, true));
-
-   /* isSplitPartDefault flag: is split partition a DEFAULT partition? */
-   isSplitPartDefault = (defaultPartOid == splitPartOid);
-
-   if (isSplitPartDefault && default_index < 0)
-   {
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("one partition in the list should be DEFAULT because split partition is DEFAULT")),
-               parser_errposition(pstate, ((SinglePartitionSpec *) linitial(partlist))->name->location));
-   }
-   else if (!isSplitPartDefault && (default_index >= 0) && OidIsValid(defaultPartOid))
-   {
-       SinglePartitionSpec *spsDef =
-           (SinglePartitionSpec *) list_nth(partlist, default_index);
-
-       ereport(ERROR,
-               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                errmsg("new partition cannot be DEFAULT because DEFAULT partition already exists")),
-               parser_errposition(pstate, spsDef->name->location));
-   }
-
-   /* Indicator that partitioned table has (or will have) DEFAULT partition */
-   existsDefaultPart = OidIsValid(defaultPartOid) || (default_index >= 0);
-
-   for (i = 0; i < nparts; i++)
-   {
-       SinglePartitionSpec *sps = new_parts[i];
-
-       if (isSplitPartDefault)
-       {
-           /*
-            * In case split partition is DEFAULT partition we can use any
-            * free ranges - as when creating a new partition.
-            */
-           check_new_partition_bound(sps->name->relname, parent, sps->bound,
-                                     pstate);
-       }
-       else
-       {
-           /*
-            * Checks that bound of current partition is inside bound of split
-            * partition. For range partitioning: checks that upper bound of
-            * previous partition is equal to lower bound of current
-            * partition. For list partitioning: checks that split partition
-            * contains all values of current partition.
-            */
-           if (strategy == PARTITION_STRATEGY_RANGE)
-           {
-               bool        first = (i == 0);
-               bool        last = (i == (nparts - 1));
-
-               check_partition_bounds_for_split_range(parent, sps->name->relname, sps->bound,
-                                                      splitPartOid, splitPartName,
-                                                      first, last,
-                                                      existsDefaultPart, pstate);
-           }
-           else
-               check_partition_bounds_for_split_list(parent, sps->name->relname,
-                                                     sps->bound, splitPartOid, pstate);
-       }
-
-       /* Ranges of new partitions should not overlap. */
-       if (strategy == PARTITION_STRATEGY_RANGE && spsPrev)
-           check_two_partitions_bounds_range(parent, spsPrev->name, spsPrev->bound,
-                                             sps->name, sps->bound, existsDefaultPart, pstate);
-
-       spsPrev = sps;
-
-       /* Check: new partitions should have different names. */
-       for (j = i + 1; j < nparts; j++)
-       {
-           SinglePartitionSpec *sps2 = new_parts[j];
-
-           if (equal(sps->name, sps2->name))
-               ereport(ERROR,
-                       (errcode(ERRCODE_DUPLICATE_TABLE),
-                        errmsg("name \"%s\" is already used", sps2->name->relname)),
-                       parser_errposition(pstate, sps2->name->location));
-       }
-   }
-
-   if (strategy == PARTITION_STRATEGY_LIST)
-   {
-       /* Values of new partitions should not overlap. */
-       check_partitions_not_overlap_list(parent, new_parts, nparts,
-                                         pstate);
-
-       /*
-        * Need to check that all values of split partition contains in new
-        * partitions. Skip this check if DEFAULT partition exists.
-        */
-       if (!existsDefaultPart)
-           check_parent_values_in_new_partitions(parent, splitPartOid,
-                                                 new_parts, nparts, pstate);
-   }
-
-   pfree(new_parts);
-}
-
-/*
- * calculate_partition_bound_for_merge
- *
- * Calculates the bound of merged partition "spec" by using the bounds of
- * partitions to be merged.
- *
- * parent:         partitioned table
- * partNames:      names of partitions to be merged
- * partOids:       Oids of partitions to be merged
- * spec (out):     bounds specification of the merged partition
- * pstate:         pointer to ParseState struct for determine error position
- */
-void
-calculate_partition_bound_for_merge(Relation parent,
-                                   List *partNames,
-                                   List *partOids,
-                                   PartitionBoundSpec *spec,
-                                   ParseState *pstate)
-{
-   PartitionKey key = RelationGetPartitionKey(parent);
-   PartitionBoundSpec *bound;
-
-   Assert(!spec->is_default);
-
-   switch (key->strategy)
-   {
-       case PARTITION_STRATEGY_RANGE:
-           {
-               int         i;
-               PartitionRangeBound **lower_bounds;
-               int         nparts = list_length(partOids);
-               List       *bounds = NIL;
-
-               lower_bounds = (PartitionRangeBound **)
-                   palloc0(nparts * sizeof(PartitionRangeBound *));
-
-               /*
-                * Create array of lower bounds and list of
-                * PartitionBoundSpec.
-                */
-               for (i = 0; i < nparts; i++)
-               {
-                   bound = get_partition_bound_spec(list_nth_oid(partOids, i),
-                                                    (RangeVar *) list_nth(partNames, i));
-
-                   lower_bounds[i] = make_one_partition_rbound(key, i, bound->lowerdatums, true);
-                   bounds = lappend(bounds, bound);
-               }
-
-               /* Sort array of lower bounds. */
-               qsort_arg(lower_bounds, nparts, sizeof(PartitionRangeBound *),
-                         qsort_partition_rbound_cmp, (void *) key);
-
-               /* Ranges of partitions should not overlap. */
-               for (i = 1; i < nparts; i++)
-               {
-                   int         index = lower_bounds[i]->index;
-                   int         prev_index = lower_bounds[i - 1]->index;
-
-                   check_two_partitions_bounds_range(parent,
-                                                     (RangeVar *) list_nth(partNames, prev_index),
-                                                     (PartitionBoundSpec *) list_nth(bounds, prev_index),
-                                                     (RangeVar *) list_nth(partNames, index),
-                                                     (PartitionBoundSpec *) list_nth(bounds, index),
-                                                     false, pstate);
-               }
-
-               /*
-                * Lower bound of first partition is the lower bound of merged
-                * partition.
-                */
-               spec->lowerdatums =
-                   ((PartitionBoundSpec *) list_nth(bounds, lower_bounds[0]->index))->lowerdatums;
-
-               /*
-                * Upper bound of last partition is the upper bound of merged
-                * partition.
-                */
-               spec->upperdatums =
-                   ((PartitionBoundSpec *) list_nth(bounds, lower_bounds[nparts - 1]->index))->upperdatums;
-
-               pfree(lower_bounds);
-               list_free(bounds);
-               break;
-           }
-
-       case PARTITION_STRATEGY_LIST:
-           {
-               ListCell   *listptr,
-                          *listptr2;
-
-               /* Consolidate bounds for all partitions in the list. */
-               forboth(listptr, partOids, listptr2, partNames)
-               {
-                   RangeVar   *name = (RangeVar *) lfirst(listptr2);
-                   Oid         curOid = lfirst_oid(listptr);
-
-                   bound = get_partition_bound_spec(curOid, name);
-                   spec->listdatums = list_concat(spec->listdatums, bound->listdatums);
-               }
-               break;
-           }
-
-       default:
-           elog(ERROR, "unexpected partition strategy: %d",
-                (int) key->strategy);
-   }
-}
index b385175e7a2bd9d8050d4fa20d65bb66b55494ad..b2ea8125c92423ecfc0529208b8dc7e701428dbc 100644 (file)
@@ -1225,12 +1225,6 @@ ProcessUtilitySlow(ParseState *pstate,
 
                            morestmts = expandTableLikeClause(table_rv, like);
                            stmts = list_concat(morestmts, stmts);
-
-                           /*
-                            * Store the OID of newly created relation to the
-                            * TableLikeClause for the caller to use it.
-                            */
-                           like->newRelationOid = address.objectId;
                        }
                        else
                        {
index 4039ee0df73ed2a0b387416069921d62cb55113b..00eda1b34c0a9106d74785045c41d7f511aecf09 100644 (file)
@@ -13296,21 +13296,3 @@ get_range_partbound_string(List *bound_datums)
 
    return buf->data;
 }
-
-/*
- * get_list_partvalue_string
- *     A C string representation of one list partition value
- */
-char *
-get_list_partvalue_string(Const *val)
-{
-   deparse_context context;
-   StringInfo  buf = makeStringInfo();
-
-   memset(&context, 0, sizeof(deparse_context));
-   context.buf = buf;
-
-   get_const_expr(val, &context, -1);
-
-   return buf->data;
-}
index 0d25981253e61e1c1cb692da662a568c0e65647a..a7ccde6d7dffc7c67bb01d12eb962849b246d916 100644 (file)
@@ -2353,7 +2353,6 @@ psql_completion(const char *text, int start, int end)
                      "OWNER TO", "SET", "VALIDATE CONSTRAINT",
                      "REPLICA IDENTITY", "ATTACH PARTITION",
                      "DETACH PARTITION", "FORCE ROW LEVEL SECURITY",
-                     "SPLIT PARTITION", "MERGE PARTITIONS (",
                      "OF", "NOT OF");
    /* ALTER TABLE xxx ADD */
    else if (Matches("ALTER", "TABLE", MatchAny, "ADD"))
@@ -2610,10 +2609,10 @@ psql_completion(const char *text, int start, int end)
        COMPLETE_WITH("FROM (", "IN (", "WITH (");
 
    /*
-    * If we have ALTER TABLE <foo> DETACH|SPLIT PARTITION, provide a list of
+    * If we have ALTER TABLE <foo> DETACH PARTITION, provide a list of
     * partitions of <foo>.
     */
-   else if (Matches("ALTER", "TABLE", MatchAny, "DETACH|SPLIT", "PARTITION"))
+   else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION"))
    {
        set_completion_reference(prev3_wd);
        COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table);
@@ -2621,19 +2620,6 @@ psql_completion(const char *text, int start, int end)
    else if (Matches("ALTER", "TABLE", MatchAny, "DETACH", "PARTITION", MatchAny))
        COMPLETE_WITH("CONCURRENTLY", "FINALIZE");
 
-   /* ALTER TABLE <name> SPLIT PARTITION <name> */
-   else if (Matches("ALTER", "TABLE", MatchAny, "SPLIT", "PARTITION", MatchAny))
-       COMPLETE_WITH("INTO ( PARTITION");
-
-   /* ALTER TABLE <name> MERGE PARTITIONS ( */
-   else if (Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "("))
-   {
-       set_completion_reference(prev4_wd);
-       COMPLETE_WITH_SCHEMA_QUERY(Query_for_partition_of_table);
-   }
-   else if (Matches("ALTER", "TABLE", MatchAny, "MERGE", "PARTITIONS", "(*)"))
-       COMPLETE_WITH("INTO");
-
    /* ALTER TABLE <name> OF */
    else if (Matches("ALTER", "TABLE", MatchAny, "OF"))
        COMPLETE_WITH_SCHEMA_QUERY(Query_for_list_of_composite_datatypes);
index 577c4bfef765fbfc63cadcad2b7c3d8f72c54cfc..124d853e499d7032553b6bc69ae2eeea1c885ab7 100644 (file)
@@ -754,7 +754,6 @@ typedef struct TableLikeClause
    RangeVar   *relation;
    bits32      options;        /* OR of TableLikeOption flags */
    Oid         relationOid;    /* If table has been looked up, its OID */
-   Oid         newRelationOid; /* OID of newly created table */
 } TableLikeClause;
 
 typedef enum TableLikeOption
@@ -938,17 +937,6 @@ typedef struct PartitionRangeDatum
    ParseLoc    location;       /* token location, or -1 if unknown */
 } PartitionRangeDatum;
 
-/*
- * PartitionDesc - info about single partition for ALTER TABLE SPLIT PARTITION command
- */
-typedef struct SinglePartitionSpec
-{
-   NodeTag     type;
-
-   RangeVar   *name;           /* name of partition */
-   PartitionBoundSpec *bound;  /* FOR VALUES, if attaching */
-} SinglePartitionSpec;
-
 /*
  * PartitionCmd - info for ALTER TABLE/INDEX ATTACH/DETACH PARTITION commands
  */
@@ -957,8 +945,6 @@ typedef struct PartitionCmd
    NodeTag     type;
    RangeVar   *name;           /* name of partition to attach/detach */
    PartitionBoundSpec *bound;  /* FOR VALUES, if attaching */
-   List       *partlist;       /* list of partitions, for MERGE/SPLIT
-                                * PARTITION command */
    bool        concurrent;
 } PartitionCmd;
 
@@ -2414,8 +2400,6 @@ typedef enum AlterTableType
    AT_AttachPartition,         /* ATTACH PARTITION */
    AT_DetachPartition,         /* DETACH PARTITION */
    AT_DetachPartitionFinalize, /* DETACH PARTITION FINALIZE */
-   AT_SplitPartition,          /* SPLIT PARTITION */
-   AT_MergePartitions,         /* MERGE PARTITIONS */
    AT_AddIdentity,             /* ADD IDENTITY */
    AT_SetIdentity,             /* SET identity column options */
    AT_DropIdentity,            /* DROP IDENTITY */
index bb191b1f469172e07371fd98928148702d367748..f8659078cedda0f159afd58fb75c0551facb5c61 100644 (file)
@@ -335,7 +335,6 @@ PG_KEYWORD("parameter", PARAMETER, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("parser", PARSER, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("partial", PARTIAL, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("partition", PARTITION, UNRESERVED_KEYWORD, BARE_LABEL)
-PG_KEYWORD("partitions", PARTITIONS, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("passing", PASSING, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("password", PASSWORD, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("path", PATH, UNRESERVED_KEYWORD, BARE_LABEL)
@@ -418,7 +417,6 @@ PG_KEYWORD("smallint", SMALLINT, COL_NAME_KEYWORD, BARE_LABEL)
 PG_KEYWORD("snapshot", SNAPSHOT, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("some", SOME, RESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("source", SOURCE, UNRESERVED_KEYWORD, BARE_LABEL)
-PG_KEYWORD("split", SPLIT, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("sql", SQL_P, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("stable", STABLE, UNRESERVED_KEYWORD, BARE_LABEL)
 PG_KEYWORD("standalone", STANDALONE_P, UNRESERVED_KEYWORD, BARE_LABEL)
index 9d2a26705f0624d314030f309124a7445ad37267..3d9cc1031f7319b1b16a1d06027f73e273299d86 100644 (file)
@@ -143,15 +143,4 @@ extern int partition_range_datum_bsearch(FmgrInfo *partsupfunc,
 extern int partition_hash_bsearch(PartitionBoundInfo boundinfo,
                                   int modulus, int remainder);
 
-extern void check_partitions_for_split(Relation parent,
-                                      Oid splitPartOid,
-                                      RangeVar *splitPartName,
-                                      List *partlist,
-                                      ParseState *pstate);
-extern void calculate_partition_bound_for_merge(Relation parent,
-                                               List *partNames,
-                                               List *partOids,
-                                               PartitionBoundSpec *spec,
-                                               ParseState *pstate);
-
 #endif                         /* PARTBOUNDS_H */
index 6d860806221ed7fc4dde830b8c62d2c2aafb8ebc..161fb5ef02c6e5b3f8391983206a0fe78a63b060 100644 (file)
@@ -49,6 +49,4 @@ extern char *get_range_partbound_string(List *bound_datums);
 
 extern char *pg_get_statisticsobjdef_string(Oid statextid);
 
-extern char *get_list_partvalue_string(Const *val);
-
 #endif                         /* RULEUTILS_H */
diff --git a/src/test/isolation/expected/partition-merge.out b/src/test/isolation/expected/partition-merge.out
deleted file mode 100644 (file)
index 98446aa..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-Parsed test spec with 2 sessions
-
-starting permutation: s2b s2i s2c s1b s1merg s2b s2u s1c s2c s2s
-step s2b: BEGIN;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1b: BEGIN;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2b s2i s2c s1brr s1merg s2b s2u s1c s2c s2s
-step s2b: BEGIN;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2b s2i s2c s1bs s1merg s2b s2u s1c s2c s2s
-step s2b: BEGIN;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2brr s2i s2c s1b s1merg s2b s2u s1c s2c s2s
-step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1b: BEGIN;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2brr s2i s2c s1brr s1merg s2b s2u s1c s2c s2s
-step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2brr s2i s2c s1bs s1merg s2b s2u s1c s2c s2s
-step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2bs s2i s2c s1b s1merg s2b s2u s1c s2c s2s
-step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1b: BEGIN;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2bs s2i s2c s1brr s1merg s2b s2u s1c s2c s2s
-step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
-
-starting permutation: s2bs s2i s2c s1bs s1merg s2b s2u s1c s2c s2s
-step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s2i: INSERT INTO tpart VALUES (1, 'text01');
-step s2c: COMMIT;
-step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s1merg: ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20;
-step s2b: BEGIN;
-step s2u: UPDATE tpart SET t = 'text01modif' where i = 1; <waiting ...>
-step s1c: COMMIT;
-step s2u: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t          
---+-----------
- 5|text05     
-15|text15     
- 1|text01modif
-25|text25     
-35|text35     
-(5 rows)
-
diff --git a/src/test/isolation/expected/partition-split.out b/src/test/isolation/expected/partition-split.out
deleted file mode 100644 (file)
index 5d9e8b0..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-Parsed test spec with 2 sessions
-
-starting permutation: s1b s1splt s2b s2i s1c s2c s2s
-step s1b: BEGIN;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2b: BEGIN;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1b s1splt s2brr s2i s1c s2c s2s
-step s1b: BEGIN;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1b s1splt s2bs s2i s1c s2c s2s
-step s1b: BEGIN;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1brr s1splt s2b s2i s1c s2c s2s
-step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2b: BEGIN;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1brr s1splt s2brr s2i s1c s2c s2s
-step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1brr s1splt s2bs s2i s1c s2c s2s
-step s1brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1bs s1splt s2b s2i s1c s2c s2s
-step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2b: BEGIN;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1bs s1splt s2brr s2i s1c s2c s2s
-step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2brr: BEGIN ISOLATION LEVEL REPEATABLE READ;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
-
-starting permutation: s1bs s1splt s2bs s2i s1c s2c s2s
-step s1bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s1splt: ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20));
-step s2bs: BEGIN ISOLATION LEVEL SERIALIZABLE;
-step s2i: INSERT INTO tpart VALUES (1, 'text01'); <waiting ...>
-step s1c: COMMIT;
-step s2i: <... completed>
-step s2c: COMMIT;
-step s2s: SELECT * FROM tpart;
- i|t     
---+------
- 5|text05
- 1|text01
-15|text15
-25|text25
-35|text35
-(5 rows)
-
index 6da98cffacad77c162707198cf2008d664f14a26..143109aa4da9ee274311dc93059332ad77f51f19 100644 (file)
@@ -106,8 +106,6 @@ test: partition-key-update-1
 test: partition-key-update-2
 test: partition-key-update-3
 test: partition-key-update-4
-test: partition-merge
-test: partition-split
 test: plpgsql-toast
 test: cluster-conflict
 test: cluster-conflict-partition
diff --git a/src/test/isolation/specs/partition-merge.spec b/src/test/isolation/specs/partition-merge.spec
deleted file mode 100644 (file)
index dc2b9d3..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-# Verify that MERGE operation locks DML operations with partitioned table
-
-setup
-{
-  DROP TABLE IF EXISTS tpart;
-  CREATE TABLE tpart(i int, t text) partition by range(i);
-  CREATE TABLE tpart_00_10 PARTITION OF tpart FOR VALUES FROM (0) TO (10);
-  CREATE TABLE tpart_10_20 PARTITION OF tpart FOR VALUES FROM (10) TO (20);
-  CREATE TABLE tpart_20_30 PARTITION OF tpart FOR VALUES FROM (20) TO (30);
-  CREATE TABLE tpart_default PARTITION OF tpart DEFAULT;
-  INSERT INTO tpart VALUES (5, 'text05');
-  INSERT INTO tpart VALUES (15, 'text15');
-  INSERT INTO tpart VALUES (25, 'text25');
-  INSERT INTO tpart VALUES (35, 'text35');
-}
-
-teardown
-{
-  DROP TABLE tpart;
-}
-
-session s1
-step s1b   { BEGIN; }
-step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step s1bs  { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step s1merg    { ALTER TABLE tpart MERGE PARTITIONS (tpart_00_10, tpart_10_20) INTO tpart_00_20; }
-step s1c   { COMMIT; }
-
-
-session s2
-step s2b   { BEGIN; }
-step s2brr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step s2bs  { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step s2i   { INSERT INTO tpart VALUES (1, 'text01'); }
-step s2u   { UPDATE tpart SET t = 'text01modif' where i = 1; }
-step s2c   { COMMIT; }
-step s2s   { SELECT * FROM tpart; }
-
-
-# s2 inserts row into table. s1 starts MERGE PARTITIONS then
-# s2 is trying to update inserted row and waits until s1 finishes
-# MERGE operation.
-
-permutation s2b s2i s2c s1b s1merg s2b s2u s1c s2c s2s
-permutation s2b s2i s2c s1brr s1merg s2b s2u s1c s2c s2s
-permutation s2b s2i s2c s1bs s1merg s2b s2u s1c s2c s2s
-
-permutation s2brr s2i s2c s1b s1merg s2b s2u s1c s2c s2s
-permutation s2brr s2i s2c s1brr s1merg s2b s2u s1c s2c s2s
-permutation s2brr s2i s2c s1bs s1merg s2b s2u s1c s2c s2s
-
-permutation s2bs s2i s2c s1b s1merg s2b s2u s1c s2c s2s
-permutation s2bs s2i s2c s1brr s1merg s2b s2u s1c s2c s2s
-permutation s2bs s2i s2c s1bs s1merg s2b s2u s1c s2c s2s
diff --git a/src/test/isolation/specs/partition-split.spec b/src/test/isolation/specs/partition-split.spec
deleted file mode 100644 (file)
index 087239a..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-# Verify that SPLIT operation locks DML operations with partitioned table
-
-setup
-{
-  DROP TABLE IF EXISTS tpart;
-  CREATE TABLE tpart(i int, t text) partition by range(i);
-  CREATE TABLE tpart_00_10 PARTITION OF tpart FOR VALUES FROM (0) TO (10);
-  CREATE TABLE tpart_10_20 PARTITION OF tpart FOR VALUES FROM (10) TO (20);
-  CREATE TABLE tpart_20_30 PARTITION OF tpart FOR VALUES FROM (20) TO (30);
-  CREATE TABLE tpart_default PARTITION OF tpart DEFAULT;
-  INSERT INTO tpart VALUES (5, 'text05');
-  INSERT INTO tpart VALUES (15, 'text15');
-  INSERT INTO tpart VALUES (25, 'text25');
-  INSERT INTO tpart VALUES (35, 'text35');
-}
-
-teardown
-{
-  DROP TABLE tpart;
-}
-
-session s1
-step s1b   { BEGIN; }
-step s1brr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step s1bs  { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step s1splt    { ALTER TABLE tpart SPLIT PARTITION tpart_10_20 INTO
-              (PARTITION tpart_10_15 FOR VALUES FROM (10) TO (15),
-               PARTITION tpart_15_20 FOR VALUES FROM (15) TO (20)); }
-step s1c   { COMMIT; }
-
-
-session s2
-step s2b   { BEGIN; }
-step s2brr { BEGIN ISOLATION LEVEL REPEATABLE READ; }
-step s2bs  { BEGIN ISOLATION LEVEL SERIALIZABLE; }
-step s2i   { INSERT INTO tpart VALUES (1, 'text01'); }
-step s2c   { COMMIT; }
-step s2s   { SELECT * FROM tpart; }
-
-
-# s1 starts SPLIT PARTITION then s2 trying to insert row and
-# waits until s1 finished SPLIT operation.
-
-permutation s1b s1splt s2b s2i s1c s2c s2s
-permutation s1b s1splt s2brr s2i s1c s2c s2s
-permutation s1b s1splt s2bs s2i s1c s2c s2s
-
-permutation s1brr s1splt s2b s2i s1c s2c s2s
-permutation s1brr s1splt s2brr s2i s1c s2c s2s
-permutation s1brr s1splt s2bs s2i s1c s2c s2s
-
-permutation s1bs s1splt s2b s2i s1c s2c s2s
-permutation s1bs s1splt s2brr s2i s1c s2c s2s
-permutation s1bs s1splt s2bs s2i s1c s2c s2s
index 67ff2b6367570c38cef8d5c918184e9b96c34a4a..2758ae82d7b4bcc234b3806808ee88514eaeee5b 100644 (file)
@@ -300,12 +300,6 @@ get_altertable_subcmdinfo(PG_FUNCTION_ARGS)
            case AT_DetachPartitionFinalize:
                strtype = "DETACH PARTITION ... FINALIZE";
                break;
-           case AT_SplitPartition:
-               strtype = "SPLIT PARTITION";
-               break;
-           case AT_MergePartitions:
-               strtype = "MERGE PARTITIONS";
-               break;
            case AT_AddIdentity:
                strtype = "ADD IDENTITY";
                break;
diff --git a/src/test/regress/expected/partition_merge.out b/src/test/regress/expected/partition_merge.out
deleted file mode 100644 (file)
index 59836e2..0000000
+++ /dev/null
@@ -1,945 +0,0 @@
---
--- PARTITIONS_MERGE
--- Tests for "ALTER TABLE ... MERGE PARTITIONS ..." command
---
-CREATE SCHEMA partitions_merge_schema;
-CREATE SCHEMA partitions_merge_schema2;
-SET search_path = partitions_merge_schema, public;
---
--- BY RANGE partitioning
---
---
--- Test for error codes
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_dec2021 PARTITION OF sales_range FOR VALUES FROM ('2021-12-01') TO ('2021-12-31');
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_apr_1 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-15');
-CREATE TABLE sales_apr_2 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-15') TO ('2022-05-01');
-ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
--- ERROR:  partition with name "sales_feb2022" is already used
-ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_feb2022) INTO sales_feb_mar_apr2022;
-ERROR:  partition with name "sales_feb2022" is already used
-LINE 1: ...e MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_feb2...
-                                                             ^
--- ERROR:  "sales_apr2022" is not a table
-ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO sales_feb_mar_apr2022;
-ERROR:  "sales_apr2022" is not a table
--- ERROR:  lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_jan2022"
--- (space between sections sales_jan2022 and sales_mar2022)
-ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_mar2022) INTO sales_jan_mar2022;
-ERROR:  lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_jan2022"
--- ERROR:  lower bound of partition "sales_jan2022" conflicts with upper bound of previous partition "sales_dec2021"
--- (space between sections sales_dec2021 and sales_jan2022)
-ALTER TABLE sales_range MERGE PARTITIONS (sales_dec2021, sales_jan2022, sales_feb2022) INTO sales_dec_jan_feb2022;
-ERROR:  lower bound of partition "sales_jan2022" conflicts with upper bound of previous partition "sales_dec2021"
--- NO ERROR: test for custom partitions order, source partitions not in the search_path
-SET search_path = partitions_merge_schema2, public;
-ALTER TABLE partitions_merge_schema.sales_range MERGE PARTITIONS (
-  partitions_merge_schema.sales_feb2022,
-  partitions_merge_schema.sales_mar2022,
-  partitions_merge_schema.sales_jan2022) INTO sales_jan_feb_mar2022;
-SET search_path = partitions_merge_schema, public;
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-                      oid                       | relkind | inhdetachpending |                   pg_get_expr                    
-------------------------------------------------+---------+------------------+--------------------------------------------------
- partitions_merge_schema2.sales_jan_feb_mar2022 | r       | f                | FOR VALUES FROM ('01-01-2022') TO ('04-01-2022')
- sales_apr2022                                  | p       | f                | FOR VALUES FROM ('04-01-2022') TO ('05-01-2022')
- sales_dec2021                                  | r       | f                | FOR VALUES FROM ('12-01-2021') TO ('12-31-2021')
- sales_others                                   | r       | f                | DEFAULT
-(4 rows)
-
-DROP TABLE sales_range;
---
--- Add rows into partitioned table, then merge partitions
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-SELECT pg_catalog.pg_get_partkeydef('sales_range'::regclass);
- pg_get_partkeydef  
---------------------
- RANGE (sales_date)
-(1 row)
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-      oid      | relkind | inhdetachpending |                   pg_get_expr                    
----------------+---------+------------------+--------------------------------------------------
- sales_apr2022 | r       | f                | FOR VALUES FROM ('04-01-2022') TO ('05-01-2022')
- sales_feb2022 | r       | f                | FOR VALUES FROM ('02-01-2022') TO ('03-01-2022')
- sales_jan2022 | r       | f                | FOR VALUES FROM ('01-01-2022') TO ('02-01-2022')
- sales_mar2022 | r       | f                | FOR VALUES FROM ('03-01-2022') TO ('04-01-2022')
- sales_others  | r       | f                | DEFAULT
-(5 rows)
-
--- check schema-qualified name of the new partition
-ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO partitions_merge_schema2.sales_feb_mar_apr2022;
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-                      oid                       | relkind | inhdetachpending |                   pg_get_expr                    
-------------------------------------------------+---------+------------------+--------------------------------------------------
- partitions_merge_schema2.sales_feb_mar_apr2022 | r       | f                | FOR VALUES FROM ('02-01-2022') TO ('05-01-2022')
- sales_jan2022                                  | r       | f                | FOR VALUES FROM ('01-01-2022') TO ('02-01-2022')
- sales_others                                   | r       | f                | DEFAULT
-(3 rows)
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_feb_mar_apr2022' and schemaname = 'partitions_merge_schema2';
-        schemaname        |       tablename       |              indexname               | tablespace |                                                           indexdef                                                           
---------------------------+-----------------------+--------------------------------------+------------+------------------------------------------------------------------------------------------------------------------------------
- partitions_merge_schema2 | sales_feb_mar_apr2022 | sales_feb_mar_apr2022_sales_date_idx |            | CREATE INDEX sales_feb_mar_apr2022_sales_date_idx ON partitions_merge_schema2.sales_feb_mar_apr2022 USING btree (sales_date)
-(1 row)
-
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_jan2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-(3 rows)
-
-SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(10 rows)
-
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             14 | Smith            |          510 | 05-04-2022
-(1 row)
-
--- Use indexscan for testing indexes
-SET enable_seqscan = OFF;
-SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022 where sales_date > '2022-01-01';
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-             11 | Trump            |          380 | 04-06-2022
-              5 | Deev             |          250 | 04-07-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-(10 rows)
-
-RESET enable_seqscan;
-DROP TABLE sales_range;
---
--- Merge some partitions into DEFAULT partition
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
--- Merge partitions (include DEFAULT partition) into partition with the same
--- name
-ALTER TABLE sales_range MERGE PARTITIONS
-  (sales_jan2022, sales_mar2022, partitions_merge_schema.sales_others) INTO sales_others;
-select * from sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-             14 | Smith            |          510 | 05-04-2022
-(7 rows)
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-      oid      | relkind | inhdetachpending |                   pg_get_expr                    
----------------+---------+------------------+--------------------------------------------------
- sales_apr2022 | r       | f                | FOR VALUES FROM ('04-01-2022') TO ('05-01-2022')
- sales_feb2022 | r       | f                | FOR VALUES FROM ('02-01-2022') TO ('03-01-2022')
- sales_others  | r       | f                | DEFAULT
-(3 rows)
-
-DROP TABLE sales_range;
---
--- Test for:
---   * composite partition key;
---   * GENERATED column;
---   * column with DEFAULT value.
---
-CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT,
-  sales_date VARCHAR(10) GENERATED ALWAYS AS
-    (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED,
-  sales_department VARCHAR(30) DEFAULT 'Sales department')
-  PARTITION BY RANGE (sales_year, sales_month, sales_day);
-CREATE TABLE sales_dec2022 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1);
-CREATE TABLE sales_jan2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1);
-CREATE TABLE sales_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1);
-CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2021, 12, 7);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2021, 12, 8);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 1, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 2, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 1, 2);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 2, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 3, 3);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 3, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 5, 1);
-SELECT * FROM sales_date;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(9 rows)
-
-SELECT * FROM sales_dec2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
-(2 rows)
-
-SELECT * FROM sales_jan2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
-(2 rows)
-
-SELECT * FROM sales_feb2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
-(2 rows)
-
-SELECT * FROM sales_other;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(3 rows)
-
-ALTER TABLE sales_date MERGE PARTITIONS (sales_jan2022, sales_feb2022) INTO sales_jan_feb2022;
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 1, 10);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 2, 10);
-SELECT * FROM sales_date;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
- Manager1         |       2022 |           1 |        10 | 2022.01.10 | Sales department
- Manager2         |       2022 |           2 |        10 | 2022.02.10 | Sales department
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(11 rows)
-
-SELECT * FROM sales_dec2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
-(2 rows)
-
-SELECT * FROM sales_jan_feb2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
- Manager1         |       2022 |           1 |        10 | 2022.01.10 | Sales department
- Manager2         |       2022 |           2 |        10 | 2022.02.10 | Sales department
-(6 rows)
-
-SELECT * FROM sales_other;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(3 rows)
-
-DROP TABLE sales_date;
---
--- Test: merge partitions of partitioned table with triggers
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
-CREATE TABLE salespeople10_20 PARTITION OF salespeople FOR VALUES FROM (10) TO (20);
-CREATE TABLE salespeople20_30 PARTITION OF salespeople FOR VALUES FROM (20) TO (30);
-CREATE TABLE salespeople30_40 PARTITION OF salespeople FOR VALUES FROM (30) TO (40);
-INSERT INTO salespeople VALUES (1,  'Poirot');
-CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$
-BEGIN
-   RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;
-    RETURN NULL;
-END;
-$BODY$;
-CREATE TRIGGER salespeople_after_insert_statement_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH STATEMENT
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
-CREATE TRIGGER salespeople_after_insert_row_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH ROW
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (10, 'May');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT
--- 1 trigger should fire here (row):
-INSERT INTO salespeople10_20 VALUES (19, 'Ivanov');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40;
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (20, 'Smirnoff');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT
--- 1 trigger should fire here (row):
-INSERT INTO salespeople10_40 VALUES (30, 'Ford');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-SELECT * FROM salespeople01_10;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-SELECT * FROM salespeople10_40;
- salesperson_id | salesperson_name 
-----------------+------------------
-             10 | May
-             19 | Ivanov
-             20 | Smirnoff
-             30 | Ford
-(4 rows)
-
-DROP TABLE salespeople;
-DROP FUNCTION after_insert_row_trigger();
---
--- Test: merge partitions with deleted columns
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
--- Create partitions with some deleted columns:
-CREATE TABLE salespeople10_20(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30));
-CREATE TABLE salespeople20_30(salesperson_id INT PRIMARY KEY, d2 INT,  salesperson_name VARCHAR(30));
-CREATE TABLE salespeople30_40(salesperson_id INT PRIMARY KEY, d3 DATE, salesperson_name VARCHAR(30));
-INSERT INTO salespeople10_20 VALUES ('dummy value 1', 19, 'Ivanov');
-INSERT INTO salespeople20_30 VALUES (20, 101, 'Smirnoff');
-INSERT INTO salespeople30_40 VALUES (31, now(), 'Popov');
-ALTER TABLE salespeople10_20 DROP COLUMN d1;
-ALTER TABLE salespeople20_30 DROP COLUMN d2;
-ALTER TABLE salespeople30_40 DROP COLUMN d3;
-ALTER TABLE salespeople ATTACH PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20);
-ALTER TABLE salespeople ATTACH PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30);
-ALTER TABLE salespeople ATTACH PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40);
-INSERT INTO salespeople VALUES (1, 'Poirot');
-INSERT INTO salespeople VALUES (10, 'May');
-INSERT INTO salespeople VALUES (30, 'Ford');
-ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40;
-select * from salespeople;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-             19 | Ivanov
-             10 | May
-             20 | Smirnoff
-             31 | Popov
-             30 | Ford
-(6 rows)
-
-select * from salespeople01_10;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-select * from salespeople10_40;
- salesperson_id | salesperson_name 
-----------------+------------------
-             19 | Ivanov
-             10 | May
-             20 | Smirnoff
-             31 | Popov
-             30 | Ford
-(5 rows)
-
-DROP TABLE salespeople;
---
--- Test: merge sub-partitions
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_apr2022_01_10 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10');
-CREATE TABLE sales_apr2022_10_20 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20');
-CREATE TABLE sales_apr2022_20_30 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01');
-ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-(4 rows)
-
-SELECT * FROM sales_apr2022_01_10;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(2 rows)
-
-SELECT * FROM sales_apr2022_10_20;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              4 | Ivanov           |          750 | 04-13-2022
-(1 row)
-
-SELECT * FROM sales_apr2022_20_30;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              3 | Ford             |         2000 | 04-30-2022
-(1 row)
-
-ALTER TABLE sales_apr2022 MERGE PARTITIONS (sales_apr2022_01_10, sales_apr2022_10_20, sales_apr2022_20_30) INTO sales_apr_all;
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-(4 rows)
-
-SELECT * FROM sales_apr_all;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-(4 rows)
-
-DROP TABLE sales_range;
---
--- BY LIST partitioning
---
---
--- Test: specific errors for BY LIST partitioning
---
-CREATE TABLE sales_list
-(salesperson_id INT GENERATED ALWAYS AS IDENTITY,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid');
-CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok');
-CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-CREATE TABLE sales_list2 (LIKE sales_list) PARTITION BY LIST (sales_state);
-CREATE TABLE sales_nord2 PARTITION OF sales_list2 FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_others2 PARTITION OF sales_list2 DEFAULT;
-CREATE TABLE sales_external (LIKE sales_list);
-CREATE TABLE sales_external2 (vch VARCHAR(5));
--- ERROR:  "sales_external" is not a partition
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external) INTO sales_all;
-ERROR:  "sales_external" is not a partition
--- ERROR:  "sales_external2" is not a partition
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external2) INTO sales_all;
-ERROR:  "sales_external2" is not a partition
--- ERROR:  relation "sales_nord2" is not a partition of relation "sales_list"
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_nord2, sales_east) INTO sales_all;
-ERROR:  relation "sales_nord2" is not a partition of relation "sales_list"
-DROP TABLE sales_external2;
-DROP TABLE sales_external;
-DROP TABLE sales_list2;
-DROP TABLE sales_list;
---
--- Test: BY LIST partitioning, MERGE PARTITIONS with data
---
-CREATE TABLE sales_list
-(salesperson_id INT GENERATED ALWAYS AS IDENTITY,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name);
-CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state);
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid');
-CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok');
-CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Trump',    'Bejing',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smirnoff', 'New York',        500, '2022-03-03');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ford',     'St. Petersburg', 2000, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ivanov',   'Warsaw',          750, '2022-03-04');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Deev',     'Lisbon',          250, '2022-03-07');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Poirot',   'Berlin',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Helsinki',       1200, '2022-03-06');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Li',       'Vladivostok',    1150, '2022-03-09');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Helsinki',       1200, '2022-03-11');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Halder',   'Oslo',            800, '2022-03-02');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Muller',   'Madrid',          650, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smith',    'Kyiv',            350, '2022-03-10');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Gandi',    'Warsaw',          150, '2022-03-08');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Plato',    'Lisbon',          950, '2022-03-05');
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_list'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-      oid      | relkind | inhdetachpending |                     pg_get_expr                      
----------------+---------+------------------+------------------------------------------------------
- sales_central | r       | f                | FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv')
- sales_east    | r       | f                | FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok')
- sales_nord    | r       | f                | FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki')
- sales_west    | r       | f                | FOR VALUES IN ('Lisbon', 'New York', 'Madrid')
- sales_others  | r       | f                | DEFAULT
-(5 rows)
-
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central) INTO sales_all;
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_list'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-     oid      | relkind | inhdetachpending |                                                 pg_get_expr                                                  
---------------+---------+------------------+--------------------------------------------------------------------------------------------------------------
- sales_all    | r       | f                | FOR VALUES IN ('Lisbon', 'New York', 'Madrid', 'Bejing', 'Delhi', 'Vladivostok', 'Warsaw', 'Berlin', 'Kyiv')
- sales_nord   | r       | f                | FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki')
- sales_others | r       | f                | DEFAULT
-(3 rows)
-
-SELECT * FROM sales_list;
- salesperson_id | salesperson_name |  sales_state   | sales_amount | sales_date 
-----------------+------------------+----------------+--------------+------------
-              2 | Smirnoff         | New York       |          500 | 03-03-2022
-              5 | Deev             | Lisbon         |          250 | 03-07-2022
-             11 | Muller           | Madrid         |          650 | 03-05-2022
-             14 | Plato            | Lisbon         |          950 | 03-05-2022
-              1 | Trump            | Bejing         |         1000 | 03-01-2022
-              8 | Li               | Vladivostok    |         1150 | 03-09-2022
-              4 | Ivanov           | Warsaw         |          750 | 03-04-2022
-              6 | Poirot           | Berlin         |         1000 | 03-01-2022
-             12 | Smith            | Kyiv           |          350 | 03-10-2022
-             13 | Gandi            | Warsaw         |          150 | 03-08-2022
-              3 | Ford             | St. Petersburg |         2000 | 03-05-2022
-              7 | May              | Helsinki       |         1200 | 03-06-2022
-              9 | May              | Helsinki       |         1200 | 03-11-2022
-             10 | Halder           | Oslo           |          800 | 03-02-2022
-(14 rows)
-
-SELECT * FROM sales_nord;
- salesperson_id | salesperson_name |  sales_state   | sales_amount | sales_date 
-----------------+------------------+----------------+--------------+------------
-              3 | Ford             | St. Petersburg |         2000 | 03-05-2022
-              7 | May              | Helsinki       |         1200 | 03-06-2022
-              9 | May              | Helsinki       |         1200 | 03-11-2022
-             10 | Halder           | Oslo           |          800 | 03-02-2022
-(4 rows)
-
-SELECT * FROM sales_all;
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              2 | Smirnoff         | New York    |          500 | 03-03-2022
-              5 | Deev             | Lisbon      |          250 | 03-07-2022
-             11 | Muller           | Madrid      |          650 | 03-05-2022
-             14 | Plato            | Lisbon      |          950 | 03-05-2022
-              1 | Trump            | Bejing      |         1000 | 03-01-2022
-              8 | Li               | Vladivostok |         1150 | 03-09-2022
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-              6 | Poirot           | Berlin      |         1000 | 03-01-2022
-             12 | Smith            | Kyiv        |          350 | 03-10-2022
-             13 | Gandi            | Warsaw      |          150 | 03-08-2022
-(10 rows)
-
--- Use indexscan for testing indexes after merging partitions
-SET enable_seqscan = OFF;
-SELECT * FROM sales_all WHERE sales_state = 'Warsaw';
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-             13 | Gandi            | Warsaw      |          150 | 03-08-2022
-(2 rows)
-
-SELECT * FROM sales_list WHERE sales_state = 'Warsaw';
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-             13 | Gandi            | Warsaw      |          150 | 03-08-2022
-(2 rows)
-
-SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov';
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-(1 row)
-
-RESET enable_seqscan;
-DROP TABLE sales_list;
---
--- Try to MERGE partitions of another table.
---
-CREATE TABLE t1 (i int, a int, b int, c int) PARTITION BY RANGE (a, b);
-CREATE TABLE t1p1 PARTITION OF t1 FOR VALUES FROM (1, 1) TO (1, 2);
-CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t);
-CREATE TABLE t2pa PARTITION OF t2 FOR VALUES FROM ('A') TO ('C');
-CREATE TABLE t3 (i int, t text);
--- ERROR:  relation "t1p1" is not a partition of relation "t2"
-ALTER TABLE t2 MERGE PARTITIONS (t1p1, t2pa) INTO t2p;
-ERROR:  relation "t1p1" is not a partition of relation "t2"
--- ERROR:  "t3" is not a partition
-ALTER TABLE t2 MERGE PARTITIONS (t2pa, t3) INTO t2p;
-ERROR:  "t3" is not a partition
-DROP TABLE t3;
-DROP TABLE t2;
-DROP TABLE t1;
---
--- Try to MERGE partitions of temporary table.
---
-CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TEMP TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TEMP TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-  oid   |        pg_get_expr         | relpersistence 
---------+----------------------------+----------------
- tp_0_1 | FOR VALUES FROM (0) TO (1) | t
- tp_1_2 | FOR VALUES FROM (1) TO (2) | t
-(2 rows)
-
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
--- Partition should be temporary.
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-  oid   |        pg_get_expr         | relpersistence 
---------+----------------------------+----------------
- tp_0_2 | FOR VALUES FROM (0) TO (2) | t
-(1 row)
-
-DROP TABLE t;
---
--- Check the partition index name if the partition name is the same as one
--- of the merged partitions.
---
-CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-CREATE INDEX tidx ON t(i);
-ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2;
--- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'.
--- Not-null constraint name should be 'tp_1_2_i_not_null'.
-\d+ tp_1_2
-                          Table "partitions_merge_schema.tp_1_2"
- Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
---------+---------+-----------+----------+---------+---------+--------------+-------------
- i      | integer |           | not null |         | plain   |              | 
-Partition of: t FOR VALUES FROM (0) TO (2)
-Partition constraint: ((i IS NOT NULL) AND (i >= 0) AND (i < 2))
-Indexes:
-    "tp_1_2_pkey" PRIMARY KEY, btree (i)
-    "tp_1_2_i_idx" btree (i)
-
-DROP TABLE t;
---
--- Try mixing permanent and temporary partitions.
---
-SET search_path = partitions_merge_schema, pg_temp, public;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
- oid | relpersistence 
------+----------------
- t   | p
-(1 row)
-
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-  oid   |        pg_get_expr         | relpersistence 
---------+----------------------------+----------------
- tp_0_1 | FOR VALUES FROM (0) TO (1) | p
- tp_1_2 | FOR VALUES FROM (1) TO (2) | p
-(2 rows)
-
-SET search_path = pg_temp, partitions_merge_schema, public;
--- Can't merge persistent partitions into a temporary partition
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-ERROR:  cannot create a temporary relation as partition of permanent relation "t"
-SET search_path = partitions_merge_schema, public;
--- Can't merge persistent partitions into a temporary partition
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
-ERROR:  cannot create a temporary relation as partition of permanent relation "t"
-DROP TABLE t;
-SET search_path = pg_temp, partitions_merge_schema, public;
-BEGIN;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
- oid | relpersistence 
------+----------------
- t   | t
-(1 row)
-
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-  oid   |        pg_get_expr         | relpersistence 
---------+----------------------------+----------------
- tp_0_1 | FOR VALUES FROM (0) TO (1) | t
- tp_1_2 | FOR VALUES FROM (1) TO (2) | t
-(2 rows)
-
-SET search_path = partitions_merge_schema, pg_temp, public;
--- Can't merge temporary partitions into a persistent partition
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-ROLLBACK;
--- Check the new partition inherits parent's tablespace
-SET search_path = partitions_merge_schema, public;
-CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace)
-  PARTITION BY RANGE (i) TABLESPACE regress_tblspace;
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-SELECT tablename, tablespace FROM pg_tables
-  WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema'
-  ORDER BY tablename, tablespace;
- tablename |    tablespace    
------------+------------------
- t         | regress_tblspace
- tp_0_2    | regress_tblspace
-(2 rows)
-
-SELECT tablename, indexname, tablespace FROM pg_indexes
-  WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema'
-  ORDER BY tablename, indexname, tablespace;
- tablename |  indexname  |    tablespace    
------------+-------------+------------------
- t         | t_pkey      | regress_tblspace
- tp_0_2    | tp_0_2_pkey | regress_tblspace
-(2 rows)
-
-DROP TABLE t;
--- Check the new partition inherits parent's table access method
-SET search_path = partitions_merge_schema, public;
-CREATE ACCESS METHOD partitions_merge_heap TYPE TABLE HANDLER heap_tableam_handler;
-CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partitions_merge_heap;
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-SELECT c.relname, a.amname
-FROM pg_class c JOIN pg_am a ON c.relam = a.oid
-WHERE c.oid IN ('t'::regclass, 'tp_0_2'::regclass)
-ORDER BY c.relname;
- relname |        amname         
----------+-----------------------
- t       | partitions_merge_heap
- tp_0_2  | partitions_merge_heap
-(2 rows)
-
-DROP TABLE t;
-DROP ACCESS METHOD partitions_merge_heap;
--- Test permission checks.  The user needs to own the parent table and all
--- the merging partitions to do the merge.
-CREATE ROLE regress_partition_merge_alice;
-CREATE ROLE regress_partition_merge_bob;
-GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_alice;
-GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_alice;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-ERROR:  must be owner of table t
-RESET SESSION AUTHORIZATION;
-ALTER TABLE t OWNER TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-ERROR:  must be owner of table tp_0_1
-RESET SESSION AUTHORIZATION;
-ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-ERROR:  must be owner of table tp_1_2
-RESET SESSION AUTHORIZATION;
-ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-RESET SESSION AUTHORIZATION;
-DROP TABLE t;
-REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_alice;
-REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_bob;
-DROP ROLE regress_partition_merge_alice;
-DROP ROLE regress_partition_merge_bob;
-RESET search_path;
---
-DROP SCHEMA partitions_merge_schema;
-DROP SCHEMA partitions_merge_schema2;
diff --git a/src/test/regress/expected/partition_split.out b/src/test/regress/expected/partition_split.out
deleted file mode 100644 (file)
index dc9a513..0000000
+++ /dev/null
@@ -1,1589 +0,0 @@
---
--- PARTITION_SPLIT
--- Tests for "ALTER TABLE ... SPLIT PARTITION ..." command
---
-CREATE SCHEMA partition_split_schema;
-CREATE SCHEMA partition_split_schema2;
-SET search_path = partition_split_schema, public;
---
--- BY RANGE partitioning
---
---
--- Test for error codes
---
-CREATE TABLE sales_range (salesperson_id int, salesperson_name varchar(30), sales_amount int, sales_date date) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
--- ERROR:  relation "sales_xxx" does not exist
-ALTER TABLE sales_range SPLIT PARTITION sales_xxx INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  relation "sales_xxx" does not exist
--- ERROR:  relation "sales_jan2022" already exists
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  relation "sales_jan2022" already exists
--- ERROR:  invalid bound specification for a range partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES IN ('2022-05-01', '2022-06-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  invalid bound specification for a range partition
-LINE 2:   (PARTITION sales_jan2022 FOR VALUES IN ('2022-05-01', '202...
-                                              ^
--- ERROR:  empty range bound specified for partition "sales_mar2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-02-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  empty range bound specified for partition "sales_mar2022"
-LINE 3:    PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO...
-                                                    ^
-DETAIL:  Specified lower bound ('03-01-2022') is greater than or equal to upper bound ('02-01-2022').
---ERROR:  list of split partitions should contain at least two items
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-10-01'));
-ERROR:  list of new partitions should contain at least two items
--- ERROR:  lower bound of partition "sales_feb2022" is less than lower bound of split partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  lower bound of partition "sales_feb2022" is less than lower bound of split partition
-LINE 2:   (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO...
-                                                    ^
--- ERROR:  name "sales_feb_mar_apr2022" is already used
--- (We can create partition with the same name as split partition, but can't create two partitions with the same name)
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  name "sales_feb_mar_apr2022" is already used
-LINE 3:    PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-03...
-                     ^
--- ERROR:  name "sales_feb2022" is already used
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  name "sales_feb2022" is already used
-LINE 3:    PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO...
-                     ^
--- ERROR:  "sales_feb_mar_apr2022" is not a partitioned table
-ALTER TABLE sales_feb_mar_apr2022 SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  "sales_feb_mar_apr2022" is not a partitioned table
--- ERROR:  upper bound of partition "sales_apr2022" is greater than upper bound of split partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01'));
-ERROR:  upper bound of partition "sales_apr2022" is greater than upper bound of split partition
-LINE 4: ... sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-0...
-                                                             ^
--- ERROR:  lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_feb2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-02-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_feb2022"
-LINE 3:    PARTITION sales_mar2022 FOR VALUES FROM ('2022-02-01') TO...
-                                                    ^
--- Tests for spaces between partitions, them should be executed without DEFAULT partition
-ALTER TABLE sales_range DETACH PARTITION sales_others;
--- ERROR:  lower bound of partition "sales_feb2022" is not equal to lower bound of split partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-ERROR:  lower bound of partition "sales_feb2022" is not equal to lower bound of split partition
-LINE 2:   (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO...
-                                                    ^
--- Check the source partition not in the search path
-SET search_path = partition_split_schema2, public;
-ALTER TABLE partition_split_schema.sales_range
-SPLIT PARTITION partition_split_schema.sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-SET search_path = partition_split_schema, public;
-\d+ sales_range
-                              Partitioned table "partition_split_schema.sales_range"
-      Column      |         Type          | Collation | Nullable | Default | Storage  | Stats target | Description 
-------------------+-----------------------+-----------+----------+---------+----------+--------------+-------------
- salesperson_id   | integer               |           |          |         | plain    |              | 
- salesperson_name | character varying(30) |           |          |         | extended |              | 
- sales_amount     | integer               |           |          |         | plain    |              | 
- sales_date       | date                  |           |          |         | plain    |              | 
-Partition key: RANGE (sales_date)
-Partitions: partition_split_schema2.sales_apr2022 FOR VALUES FROM ('04-01-2022') TO ('05-01-2022'),
-            partition_split_schema2.sales_feb2022 FOR VALUES FROM ('02-01-2022') TO ('03-01-2022'),
-            partition_split_schema2.sales_mar2022 FOR VALUES FROM ('03-01-2022') TO ('04-01-2022'),
-            sales_jan2022 FOR VALUES FROM ('01-01-2022') TO ('02-01-2022')
-
-DROP TABLE sales_range;
-DROP TABLE sales_others;
---
--- Add rows into partitioned table then split partition
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_jan2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-(3 rows)
-
-SELECT * FROM sales_feb2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-(3 rows)
-
-SELECT * FROM sales_mar2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-(3 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(4 rows)
-
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             14 | Smith            |          510 | 05-04-2022
-(1 row)
-
-DROP TABLE sales_range CASCADE;
---
--- Add split partition, then add rows into partitioned table
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
--- Split partition, also check schema qualification of new partitions
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION partition_split_schema.sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION partition_split_schema2.sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-\d+ sales_range
-                              Partitioned table "partition_split_schema.sales_range"
-      Column      |         Type          | Collation | Nullable | Default | Storage  | Stats target | Description 
-------------------+-----------------------+-----------+----------+---------+----------+--------------+-------------
- salesperson_id   | integer               |           |          |         | plain    |              | 
- salesperson_name | character varying(30) |           |          |         | extended |              | 
- sales_amount     | integer               |           |          |         | plain    |              | 
- sales_date       | date                  |           |          |         | plain    |              | 
-Partition key: RANGE (sales_date)
-Partitions: partition_split_schema2.sales_mar2022 FOR VALUES FROM ('03-01-2022') TO ('04-01-2022'),
-            sales_apr2022 FOR VALUES FROM ('04-01-2022') TO ('05-01-2022'),
-            sales_feb2022 FOR VALUES FROM ('02-01-2022') TO ('03-01-2022'),
-            sales_jan2022 FOR VALUES FROM ('01-01-2022') TO ('02-01-2022'),
-            sales_others DEFAULT
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_jan2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-(3 rows)
-
-SELECT * FROM sales_feb2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-(3 rows)
-
-SELECT * FROM partition_split_schema2.sales_mar2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-(3 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(4 rows)
-
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             14 | Smith            |          510 | 05-04-2022
-(1 row)
-
-DROP TABLE sales_range CASCADE;
---
--- Test for:
---   * composite partition key;
---   * GENERATED column;
---   * column with DEFAULT value.
---
-CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT,
-  sales_date VARCHAR(10) GENERATED ALWAYS AS
-    (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED,
-  sales_department VARCHAR(30) DEFAULT 'Sales department')
-  PARTITION BY RANGE (sales_year, sales_month, sales_day);
-CREATE TABLE sales_dec2022 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1);
-CREATE TABLE sales_jan_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 3, 1);
-CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2021, 12, 7);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2021, 12, 8);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 1, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 2, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 1, 2);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 2, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 3, 3);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 3, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 5, 1);
-SELECT * FROM sales_date;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(9 rows)
-
-SELECT * FROM sales_dec2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
-(2 rows)
-
-SELECT * FROM sales_jan_feb2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
-(4 rows)
-
-SELECT * FROM sales_other;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(3 rows)
-
-ALTER TABLE sales_date SPLIT PARTITION sales_jan_feb2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1),
-   PARTITION sales_feb2022 FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1));
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 1, 10);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 2, 10);
-SELECT * FROM sales_date;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager1         |       2022 |           1 |        10 | 2022.01.10 | Sales department
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
- Manager2         |       2022 |           2 |        10 | 2022.02.10 | Sales department
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(11 rows)
-
-SELECT * FROM sales_dec2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2021 |          12 |         7 | 2021.12.07 | Sales department
- Manager2         |       2021 |          12 |         8 | 2021.12.08 | Sales department
-(2 rows)
-
-SELECT * FROM sales_jan2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager3         |       2022 |           1 |         1 | 2022.01.01 | Sales department
- Manager2         |       2022 |           1 |         2 | 2022.01.02 | Sales department
- Manager1         |       2022 |           1 |        10 | 2022.01.10 | Sales department
-(3 rows)
-
-SELECT * FROM sales_feb2022;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2022 |           2 |         4 | 2022.02.04 | Sales department
- Manager3         |       2022 |           2 |         1 | 2022.02.01 | Sales department
- Manager2         |       2022 |           2 |        10 | 2022.02.10 | Sales department
-(3 rows)
-
-SELECT * FROM sales_other;
- salesperson_name | sales_year | sales_month | sales_day | sales_date | sales_department 
-------------------+------------+-------------+-----------+------------+------------------
- Manager1         |       2022 |           3 |         3 | 2022.03.03 | Sales department
- Manager2         |       2022 |           3 |         4 | 2022.03.04 | Sales department
- Manager3         |       2022 |           5 |         1 | 2022.05.01 | Sales department
-(3 rows)
-
---ERROR:  relation "sales_jan_feb2022" does not exist
-SELECT * FROM sales_jan_feb2022;
-ERROR:  relation "sales_jan_feb2022" does not exist
-LINE 1: SELECT * FROM sales_jan_feb2022;
-                      ^
-DROP TABLE sales_date CASCADE;
---
--- Test: split DEFAULT partition; use an index on partition key; check index after split
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-              6 | Poirot           |          150 | 02-11-2022
-              7 | Li               |          175 | 03-08-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              9 | Muller           |          250 | 03-11-2022
-             11 | Trump            |          380 | 04-06-2022
-             12 | Plato            |          350 | 03-19-2022
-             14 | Smith            |          510 | 05-04-2022
-(11 rows)
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_others' and schemaname = 'partition_split_schema' ORDER BY indexname;
-       schemaname       |  tablename   |          indexname          | tablespace |                                                 indexdef                                                 
-------------------------+--------------+-----------------------------+------------+----------------------------------------------------------------------------------------------------------
- partition_split_schema | sales_others | sales_others_sales_date_idx |            | CREATE INDEX sales_others_sales_date_idx ON partition_split_schema.sales_others USING btree (sales_date)
-(1 row)
-
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'),
-   PARTITION sales_others DEFAULT);
--- Use indexscan for testing indexes
-SET enable_indexscan = ON;
-SET enable_seqscan = OFF;
-SELECT * FROM sales_feb2022 where sales_date > '2022-01-01';
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-(3 rows)
-
-SELECT * FROM sales_mar2022 where sales_date > '2022-01-01';
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-(3 rows)
-
-SELECT * FROM sales_apr2022 where sales_date > '2022-01-01';
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             11 | Trump            |          380 | 04-06-2022
-              5 | Deev             |          250 | 04-07-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-(4 rows)
-
-SELECT * FROM sales_others where sales_date > '2022-01-01';
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             14 | Smith            |          510 | 05-04-2022
-(1 row)
-
-SET enable_indexscan = ON;
-SET enable_seqscan = ON;
-SELECT * FROM pg_indexes WHERE tablename = 'sales_feb2022' and schemaname = 'partition_split_schema' ORDER BY indexname;
-       schemaname       |   tablename   |          indexname           | tablespace |                                                  indexdef                                                  
-------------------------+---------------+------------------------------+------------+------------------------------------------------------------------------------------------------------------
- partition_split_schema | sales_feb2022 | sales_feb2022_sales_date_idx |            | CREATE INDEX sales_feb2022_sales_date_idx ON partition_split_schema.sales_feb2022 USING btree (sales_date)
-(1 row)
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_mar2022' and schemaname = 'partition_split_schema' ORDER BY indexname;
-       schemaname       |   tablename   |          indexname           | tablespace |                                                  indexdef                                                  
-------------------------+---------------+------------------------------+------------+------------------------------------------------------------------------------------------------------------
- partition_split_schema | sales_mar2022 | sales_mar2022_sales_date_idx |            | CREATE INDEX sales_mar2022_sales_date_idx ON partition_split_schema.sales_mar2022 USING btree (sales_date)
-(1 row)
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_apr2022' and schemaname = 'partition_split_schema' ORDER BY indexname;
-       schemaname       |   tablename   |          indexname           | tablespace |                                                  indexdef                                                  
-------------------------+---------------+------------------------------+------------+------------------------------------------------------------------------------------------------------------
- partition_split_schema | sales_apr2022 | sales_apr2022_sales_date_idx |            | CREATE INDEX sales_apr2022_sales_date_idx ON partition_split_schema.sales_apr2022 USING btree (sales_date)
-(1 row)
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_others' and schemaname = 'partition_split_schema' ORDER BY indexname;
-       schemaname       |  tablename   |          indexname           | tablespace |                                                 indexdef                                                  
-------------------------+--------------+------------------------------+------------+-----------------------------------------------------------------------------------------------------------
- partition_split_schema | sales_others | sales_others_sales_date_idx1 |            | CREATE INDEX sales_others_sales_date_idx1 ON partition_split_schema.sales_others USING btree (sales_date)
-(1 row)
-
-DROP TABLE sales_range CASCADE;
---
--- Test: some cases for splitting DEFAULT partition (different bounds)
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date INT) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
--- sales_error intersects with sales_dec2022 (lower bound)
--- ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20211230) TO (20220201),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-LINE 3:    PARTITION sales_error FOR VALUES FROM (20211230) TO (2022...
-                                                  ^
--- sales_error intersects with sales_feb2022 (upper bound)
--- ERROR:  lower bound of partition "sales_feb2022" conflicts with upper bound of previous partition "sales_error"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20220101) TO (20220202),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-ERROR:  lower bound of partition "sales_feb2022" conflicts with upper bound of previous partition "sales_error"
-LINE 4:    PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20...
-                                                    ^
--- sales_error intersects with sales_dec2022 (inside bound)
--- ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20211210) TO (20211220),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-LINE 3:    PARTITION sales_error FOR VALUES FROM (20211210) TO (2021...
-                                                  ^
--- sales_error intersects with sales_dec2022 (exactly the same bounds)
--- ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-LINE 3:    PARTITION sales_error FOR VALUES FROM (20211201) TO (2022...
-                                                  ^
--- ERROR:  all partitions in the list should be DEFAULT because split partition is DEFAULT
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_jan2022 FOR VALUES FROM (20220101) TO (20220201),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301));
-ERROR:  one partition in the list should be DEFAULT because split partition is DEFAULT
-LINE 2:   (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20...
-                     ^
--- no error: bounds of sales_noerror are between sales_dec2022 and sales_feb2022
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_noerror FOR VALUES FROM (20220110) TO (20220120),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-DROP TABLE sales_range;
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date INT) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
--- no error: bounds of sales_noerror are equal to lower and upper bounds of sales_dec2022 and sales_feb2022
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_noerror FOR VALUES FROM (20210101) TO (20210201),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-DROP TABLE sales_range;
---
--- Test: split partition with CHECK and FOREIGN KEY CONSTRAINTs on partitioned table
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30));
-INSERT INTO salespeople VALUES (1,  'Poirot');
-CREATE TABLE sales_range (
-salesperson_id INT REFERENCES salespeople(salesperson_id),
-sales_amount INT CHECK (sales_amount > 1),
-sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb_mar_apr2022'::regclass::oid ORDER BY conname;
-                        pg_get_constraintdef                         |             conname             | conkey 
----------------------------------------------------------------------+---------------------------------+--------
- CHECK ((sales_amount > 1))                                          | sales_range_sales_amount_check  | {2}
- FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1}
-(2 rows)
-
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
--- We should see the same CONSTRAINTs as on sales_feb_mar_apr2022 partition
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb2022'::regclass::oid ORDER BY conname;;
-                        pg_get_constraintdef                         |             conname             | conkey 
----------------------------------------------------------------------+---------------------------------+--------
- CHECK ((sales_amount > 1))                                          | sales_range_sales_amount_check  | {2}
- FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1}
-(2 rows)
-
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_mar2022'::regclass::oid ORDER BY conname;;
-                        pg_get_constraintdef                         |             conname             | conkey 
----------------------------------------------------------------------+---------------------------------+--------
- CHECK ((sales_amount > 1))                                          | sales_range_sales_amount_check  | {2}
- FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1}
-(2 rows)
-
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_apr2022'::regclass::oid ORDER BY conname;;
-                        pg_get_constraintdef                         |             conname             | conkey 
----------------------------------------------------------------------+---------------------------------+--------
- CHECK ((sales_amount > 1))                                          | sales_range_sales_amount_check  | {2}
- FOREIGN KEY (salesperson_id) REFERENCES salespeople(salesperson_id) | sales_range_salesperson_id_fkey | {1}
-(2 rows)
-
--- ERROR:  new row for relation "sales_mar2022" violates check constraint "sales_range_sales_amount_check"
-INSERT INTO sales_range VALUES (1, 0, '2022-03-11');
-ERROR:  new row for relation "sales_mar2022" violates check constraint "sales_range_sales_amount_check"
-DETAIL:  Failing row contains (1, 0, 03-11-2022).
--- ERROR:  insert or update on table "sales_mar2022" violates foreign key constraint "sales_range_salesperson_id_fkey"
-INSERT INTO sales_range VALUES (-1, 10, '2022-03-11');
-ERROR:  insert or update on table "sales_mar2022" violates foreign key constraint "sales_range_salesperson_id_fkey"
-DETAIL:  Key (salesperson_id)=(-1) is not present in table "salespeople".
--- ok
-INSERT INTO sales_range VALUES (1, 10, '2022-03-11');
-DROP TABLE sales_range CASCADE;
-DROP TABLE salespeople CASCADE;
---
--- Test: split partition on partitioned table in case of existing FOREIGN KEY reference from another table
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE sales (salesperson_id INT REFERENCES salespeople(salesperson_id), sales_amount INT, sales_date DATE);
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
-CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40);
-INSERT INTO salespeople VALUES (1,  'Poirot');
-INSERT INTO salespeople VALUES (10, 'May');
-INSERT INTO salespeople VALUES (19, 'Ivanov');
-INSERT INTO salespeople VALUES (20, 'Smirnoff');
-INSERT INTO salespeople VALUES (30, 'Ford');
-INSERT INTO sales VALUES (1,  100, '2022-03-01');
-INSERT INTO sales VALUES (1,  110, '2022-03-02');
-INSERT INTO sales VALUES (10, 150, '2022-03-01');
-INSERT INTO sales VALUES (10, 90,  '2022-03-03');
-INSERT INTO sales VALUES (19, 200, '2022-03-04');
-INSERT INTO sales VALUES (20, 50,  '2022-03-12');
-INSERT INTO sales VALUES (20, 170, '2022-03-02');
-INSERT INTO sales VALUES (30, 30,  '2022-03-04');
-SELECT * FROM salespeople01_10;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-SELECT * FROM salespeople10_40;
- salesperson_id | salesperson_name 
-----------------+------------------
-             10 | May
-             19 | Ivanov
-             20 | Smirnoff
-             30 | Ford
-(4 rows)
-
-ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO
-  (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20),
-   PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30),
-   PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40));
-SELECT * FROM salespeople01_10;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-SELECT * FROM salespeople10_20;
- salesperson_id | salesperson_name 
-----------------+------------------
-             10 | May
-             19 | Ivanov
-(2 rows)
-
-SELECT * FROM salespeople20_30;
- salesperson_id | salesperson_name 
-----------------+------------------
-             20 | Smirnoff
-(1 row)
-
-SELECT * FROM salespeople30_40;
- salesperson_id | salesperson_name 
-----------------+------------------
-             30 | Ford
-(1 row)
-
--- ERROR:  insert or update on table "sales" violates foreign key constraint "sales_salesperson_id_fkey"
-INSERT INTO sales VALUES (40, 50,  '2022-03-04');
-ERROR:  insert or update on table "sales" violates foreign key constraint "sales_salesperson_id_fkey"
-DETAIL:  Key (salesperson_id)=(40) is not present in table "salespeople".
--- ok
-INSERT INTO sales VALUES (30, 50,  '2022-03-04');
-DROP TABLE sales CASCADE;
-DROP TABLE salespeople CASCADE;
---
--- Test: split partition of partitioned table with triggers
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
-CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40);
-INSERT INTO salespeople VALUES (1,  'Poirot');
-CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$
-BEGIN
-   RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;
-    RETURN NULL;
-END;
-$BODY$;
-CREATE TRIGGER salespeople_after_insert_statement_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH STATEMENT
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
-CREATE TRIGGER salespeople_after_insert_row_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH ROW
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (10, 'May');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT
--- 1 trigger should fire here (row):
-INSERT INTO salespeople10_40 VALUES (19, 'Ivanov');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO
-  (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20),
-   PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30),
-   PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40));
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (20, 'Smirnoff');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = STATEMENT
--- 1 trigger should fire here (row):
-INSERT INTO salespeople30_40 VALUES (30, 'Ford');
-NOTICE:  trigger(salespeople) called: action = INSERT, when = AFTER, level = ROW
-SELECT * FROM salespeople01_10;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-SELECT * FROM salespeople10_20;
- salesperson_id | salesperson_name 
-----------------+------------------
-             10 | May
-             19 | Ivanov
-(2 rows)
-
-SELECT * FROM salespeople20_30;
- salesperson_id | salesperson_name 
-----------------+------------------
-             20 | Smirnoff
-(1 row)
-
-SELECT * FROM salespeople30_40;
- salesperson_id | salesperson_name 
-----------------+------------------
-             30 | Ford
-(1 row)
-
-DROP TABLE salespeople CASCADE;
-DROP FUNCTION after_insert_row_trigger();
---
--- Test: split partition witch identity column
--- If split partition column is identity column, columns of new partitions are identity columns too.
---
-CREATE TABLE salespeople(salesperson_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE salespeople1_2 PARTITION OF salespeople FOR VALUES FROM (1) TO (2);
--- Create new partition with identity column:
-CREATE TABLE salespeople2_5(salesperson_id INT NOT NULL, salesperson_name VARCHAR(30));
-ALTER TABLE salespeople ATTACH PARTITION salespeople2_5 FOR VALUES FROM (2) TO (5);
-INSERT INTO salespeople (salesperson_name) VALUES ('Poirot');
-INSERT INTO salespeople (salesperson_name) VALUES ('Ivanov');
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople1_2'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
--- Split partition has identity column:
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople2_5'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
-ALTER TABLE salespeople SPLIT PARTITION salespeople2_5 INTO
-  (PARTITION salespeople2_3 FOR VALUES FROM (2) TO (3),
-   PARTITION salespeople3_4 FOR VALUES FROM (3) TO (4),
-   PARTITION salespeople4_5 FOR VALUES FROM (4) TO (5));
-INSERT INTO salespeople (salesperson_name) VALUES ('May');
-INSERT INTO salespeople (salesperson_name) VALUES ('Ford');
-SELECT * FROM salespeople1_2;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-SELECT * FROM salespeople2_3;
- salesperson_id | salesperson_name 
-----------------+------------------
-              2 | Ivanov
-(1 row)
-
-SELECT * FROM salespeople3_4;
- salesperson_id | salesperson_name 
-----------------+------------------
-              3 | May
-(1 row)
-
-SELECT * FROM salespeople4_5;
- salesperson_id | salesperson_name 
-----------------+------------------
-              4 | Ford
-(1 row)
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople1_2'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
--- New partitions have identity-columns:
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople2_3'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople3_4'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople4_5'::regclass::oid ORDER BY attnum;
-     attname      | attidentity | attgenerated 
-------------------+-------------+--------------
- salesperson_id   | a           | 
- salesperson_name |             | 
-(2 rows)
-
-DROP TABLE salespeople CASCADE;
---
--- Test: split partition with deleted columns
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
--- Create new partition with some deleted columns:
-CREATE TABLE salespeople10_40(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, d2 INT, d3 DATE, salesperson_name VARCHAR(30));
-INSERT INTO salespeople10_40 VALUES ('dummy value 1', 19, 100, now(), 'Ivanov');
-INSERT INTO salespeople10_40 VALUES ('dummy value 2', 20, 101, now(), 'Smirnoff');
-ALTER TABLE salespeople10_40 DROP COLUMN d1;
-ALTER TABLE salespeople10_40 DROP COLUMN d2;
-ALTER TABLE salespeople10_40 DROP COLUMN d3;
-ALTER TABLE salespeople ATTACH PARTITION salespeople10_40 FOR VALUES FROM (10) TO (40);
-INSERT INTO salespeople VALUES (1, 'Poirot');
-INSERT INTO salespeople VALUES (10, 'May');
-INSERT INTO salespeople VALUES (30, 'Ford');
-ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO
-  (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20),
-   PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30),
-   PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40));
-select * from salespeople01_10;
- salesperson_id | salesperson_name 
-----------------+------------------
-              1 | Poirot
-(1 row)
-
-select * from salespeople10_20;
- salesperson_id | salesperson_name 
-----------------+------------------
-             19 | Ivanov
-             10 | May
-(2 rows)
-
-select * from salespeople20_30;
- salesperson_id | salesperson_name 
-----------------+------------------
-             20 | Smirnoff
-(1 row)
-
-select * from salespeople30_40;
- salesperson_id | salesperson_name 
-----------------+------------------
-             30 | Ford
-(1 row)
-
-DROP TABLE salespeople CASCADE;
---
--- Test: split sub-partition
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_apr_all PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(4 rows)
-
-ALTER TABLE sales_apr2022 SPLIT PARTITION sales_apr_all INTO
-  (PARTITION sales_apr2022_01_10 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'),
-   PARTITION sales_apr2022_10_20 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20'),
-   PARTITION sales_apr2022_20_30 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01'));
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              3 | Ford             |         2000 | 04-30-2022
-(4 rows)
-
-SELECT * FROM sales_apr2022_01_10;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(2 rows)
-
-SELECT * FROM sales_apr2022_10_20;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              4 | Ivanov           |          750 | 04-13-2022
-(1 row)
-
-SELECT * FROM sales_apr2022_20_30;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              3 | Ford             |         2000 | 04-30-2022
-(1 row)
-
-DROP TABLE sales_range;
---
--- BY LIST partitioning
---
---
--- Test: specific errors for BY LIST partitioning
---
-CREATE TABLE sales_list
-(salesperson_id INT,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Bejing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
--- ERROR:  new partition "sales_east" would overlap with another (not split) partition "sales_nord"
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok', 'Helsinki'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-ERROR:  new partition "sales_east" would overlap with another (not split) partition "sales_nord"
-LINE 3: ... FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok', 'Helsinki'...
-                                                             ^
--- ERROR:  new partition "sales_west" would overlap with another new partition "sales_central"
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Lisbon', 'Kyiv'));
-ERROR:  new partition "sales_west" would overlap with another new partition "sales_central"
-LINE 2:   (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York',...
-                                               ^
--- ERROR:  new partition "sales_west" cannot have NULL value because split partition does not have
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', NULL),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-ERROR:  new partition "sales_west" cannot have NULL value because split partition does not have
-LINE 2: ...s_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', NULL),
-                                                                 ^
-DROP TABLE sales_list;
---
--- Test: two specific errors for BY LIST partitioning:
---   * new partitions do not have NULL value, which split partition has.
---   * new partitions do not have a value that split partition has.
---
-CREATE TABLE sales_list
-(salesperson_id INT,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo');
-CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Bejing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok', NULL);
--- ERROR:  new partitions do not have value NULL but split partition does
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-ERROR:  new partitions do not have value NULL but split partition does
--- ERROR:  new partitions do not have value 'Kyiv' but split partition does
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', NULL));
-ERROR:  new partitions do not have value 'Kyiv' but split partition does
-DROP TABLE sales_list;
---
--- Test: BY LIST partitioning, SPLIT PARTITION with data
---
-CREATE TABLE sales_list
-(salesperson_id SERIAL,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name);
-CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state);
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo');
-CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Bejing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Trump',    'Bejing',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smirnoff', 'New York',        500, '2022-03-03');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ford',     'St. Petersburg', 2000, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ivanov',   'Warsaw',          750, '2022-03-04');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Deev',     'Lisbon',          250, '2022-03-07');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Poirot',   'Berlin',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Oslo',           1200, '2022-03-06');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Li',       'Vladivostok',    1150, '2022-03-09');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Oslo',           1200, '2022-03-11');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Halder',   'Helsinki',        800, '2022-03-02');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Muller',   'Madrid',          650, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smith',    'Kyiv',            350, '2022-03-10');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Gandi',    'Warsaw',          150, '2022-03-08');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Plato',    'Lisbon',          950, '2022-03-05');
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-SELECT * FROM sales_list;
- salesperson_id | salesperson_name |  sales_state   | sales_amount | sales_date 
-----------------+------------------+----------------+--------------+------------
-              1 | Trump            | Bejing         |         1000 | 03-01-2022
-              8 | Li               | Vladivostok    |         1150 | 03-09-2022
-              4 | Ivanov           | Warsaw         |          750 | 03-04-2022
-              6 | Poirot           | Berlin         |         1000 | 03-01-2022
-             12 | Smith            | Kyiv           |          350 | 03-10-2022
-             13 | Gandi            | Warsaw         |          150 | 03-08-2022
-              3 | Ford             | St. Petersburg |         2000 | 03-05-2022
-              7 | May              | Oslo           |         1200 | 03-06-2022
-              9 | May              | Oslo           |         1200 | 03-11-2022
-             10 | Halder           | Helsinki       |          800 | 03-02-2022
-              2 | Smirnoff         | New York       |          500 | 03-03-2022
-              5 | Deev             | Lisbon         |          250 | 03-07-2022
-             11 | Muller           | Madrid         |          650 | 03-05-2022
-             14 | Plato            | Lisbon         |          950 | 03-05-2022
-(14 rows)
-
-SELECT * FROM sales_west;
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              2 | Smirnoff         | New York    |          500 | 03-03-2022
-              5 | Deev             | Lisbon      |          250 | 03-07-2022
-             11 | Muller           | Madrid      |          650 | 03-05-2022
-             14 | Plato            | Lisbon      |          950 | 03-05-2022
-(4 rows)
-
-SELECT * FROM sales_east;
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              1 | Trump            | Bejing      |         1000 | 03-01-2022
-              8 | Li               | Vladivostok |         1150 | 03-09-2022
-(2 rows)
-
-SELECT * FROM sales_nord;
- salesperson_id | salesperson_name |  sales_state   | sales_amount | sales_date 
-----------------+------------------+----------------+--------------+------------
-              3 | Ford             | St. Petersburg |         2000 | 03-05-2022
-              7 | May              | Oslo           |         1200 | 03-06-2022
-              9 | May              | Oslo           |         1200 | 03-11-2022
-             10 | Halder           | Helsinki       |          800 | 03-02-2022
-(4 rows)
-
-SELECT * FROM sales_central;
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-              6 | Poirot           | Berlin      |         1000 | 03-01-2022
-             12 | Smith            | Kyiv        |          350 | 03-10-2022
-             13 | Gandi            | Warsaw      |          150 | 03-08-2022
-(4 rows)
-
--- Use indexscan for testing indexes after splitting partition
-SET enable_indexscan = ON;
-SET enable_seqscan = OFF;
-SELECT * FROM sales_central WHERE sales_state = 'Warsaw';
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-             13 | Gandi            | Warsaw      |          150 | 03-08-2022
-(2 rows)
-
-SELECT * FROM sales_list WHERE sales_state = 'Warsaw';
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-             13 | Gandi            | Warsaw      |          150 | 03-08-2022
-(2 rows)
-
-SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov';
- salesperson_id | salesperson_name | sales_state | sales_amount | sales_date 
-----------------+------------------+-------------+--------------+------------
-              4 | Ivanov           | Warsaw      |          750 | 03-04-2022
-(1 row)
-
-SET enable_indexscan = ON;
-SET enable_seqscan = ON;
-DROP TABLE sales_list;
---
--- Test for:
---   * split DEFAULT partition to partitions with spaces between bounds;
---   * random order of partitions in SPLIT PARTITION command.
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-09');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-07');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_others DEFAULT,
-   PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'),
-   PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'),
-   PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'),
-   PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'));
-SELECT * FROM sales_jan2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             13 | Gandi            |          377 | 01-09-2022
-(1 row)
-
-SELECT * FROM sales_feb2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-09-2022
-              6 | Poirot           |          150 | 02-07-2022
-(2 rows)
-
-SELECT * FROM sales_mar2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              7 | Li               |          175 | 03-08-2022
-(1 row)
-
-SELECT * FROM sales_apr2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(2 rows)
-
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              9 | Muller           |          250 | 03-11-2022
-             10 | Halder           |          350 | 01-28-2022
-             12 | Plato            |          350 | 03-19-2022
-             14 | Smith            |          510 | 05-04-2022
-(8 rows)
-
-DROP TABLE sales_range;
---
--- Test for:
---   * split non-DEFAULT partition to partitions with spaces between bounds;
---   * random order of partitions in SPLIT PARTITION command.
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-09');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-07');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-ALTER TABLE sales_range SPLIT PARTITION sales_all INTO
-  (PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'),
-   PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'),
-   PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'),
-   PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'));
-SELECT * FROM sales_jan2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             13 | Gandi            |          377 | 01-09-2022
-(1 row)
-
-SELECT * FROM sales_feb2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-09-2022
-              6 | Poirot           |          150 | 02-07-2022
-(2 rows)
-
-SELECT * FROM sales_mar2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              7 | Li               |          175 | 03-08-2022
-(1 row)
-
-SELECT * FROM sales_apr2022_1decade;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(2 rows)
-
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-             14 | Smith            |          510 | 05-04-2022
-              1 | May              |         1000 | 01-31-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              9 | Muller           |          250 | 03-11-2022
-             10 | Halder           |          350 | 01-28-2022
-             12 | Plato            |          350 | 03-19-2022
-(8 rows)
-
-DROP TABLE sales_range;
---
--- Test for split non-DEFAULT partition to DEFAULT partition + partitions
--- with spaces between bounds.
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-ALTER TABLE sales_range SPLIT PARTITION sales_all INTO
-  (PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'),
-   PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_others DEFAULT);
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-SELECT * FROM sales_range;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-             14 | Smith            |          510 | 05-04-2022
-(14 rows)
-
-SELECT * FROM sales_jan2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              1 | May              |         1000 | 01-31-2022
-             10 | Halder           |          350 | 01-28-2022
-             13 | Gandi            |          377 | 01-09-2022
-(3 rows)
-
-SELECT * FROM sales_feb2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              2 | Smirnoff         |          500 | 02-10-2022
-              6 | Poirot           |          150 | 02-11-2022
-              8 | Ericsson         |          185 | 02-23-2022
-(3 rows)
-
-SELECT * FROM sales_apr2022;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              3 | Ford             |         2000 | 04-30-2022
-              4 | Ivanov           |          750 | 04-13-2022
-              5 | Deev             |          250 | 04-07-2022
-             11 | Trump            |          380 | 04-06-2022
-(4 rows)
-
-SELECT * FROM sales_others;
- salesperson_id | salesperson_name | sales_amount | sales_date 
-----------------+------------------+--------------+------------
-              7 | Li               |          175 | 03-08-2022
-              9 | Muller           |          250 | 03-11-2022
-             12 | Plato            |          350 | 03-19-2022
-             14 | Smith            |          510 | 05-04-2022
-(4 rows)
-
-DROP TABLE sales_range;
---
--- Try to SPLIT partition of another table.
---
-CREATE TABLE t1(i int, t text) PARTITION BY LIST (t);
-CREATE TABLE t1pa PARTITION OF t1 FOR VALUES IN ('A');
-CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t);
--- ERROR:  relation "t1pa" is not a partition of relation "t2"
-ALTER TABLE t2 SPLIT PARTITION t1pa INTO
-   (PARTITION t2a FOR VALUES FROM ('A') TO ('B'),
-    PARTITION t2b FOR VALUES FROM ('B') TO ('C'));
-ERROR:  relation "t1pa" is not a partition of relation "t2"
-DROP TABLE t2;
-DROP TABLE t1;
---
--- Try to SPLIT partition of temporary table.
---
-CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TEMP TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-  oid   |        pg_get_expr         | relpersistence 
---------+----------------------------+----------------
- tp_0_2 | FOR VALUES FROM (0) TO (2) | t
-(1 row)
-
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
--- Partitions should be temporary.
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-  oid   |        pg_get_expr         | relpersistence 
---------+----------------------------+----------------
- tp_0_1 | FOR VALUES FROM (0) TO (1) | t
- tp_1_2 | FOR VALUES FROM (1) TO (2) | t
-(2 rows)
-
-DROP TABLE t;
--- Check the new partitions inherit parent's tablespace
-CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace)
-  PARTITION BY RANGE (i) TABLESPACE regress_tblspace;
-CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-SELECT tablename, tablespace FROM pg_tables
-  WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema'
-  ORDER BY tablename, tablespace;
- tablename |    tablespace    
------------+------------------
- t         | regress_tblspace
- tp_0_1    | regress_tblspace
- tp_1_2    | regress_tblspace
-(3 rows)
-
-SELECT tablename, indexname, tablespace FROM pg_indexes
-  WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema'
-  ORDER BY tablename, indexname, tablespace;
- tablename |  indexname  |    tablespace    
------------+-------------+------------------
- t         | t_pkey      | regress_tblspace
- tp_0_1    | tp_0_1_pkey | regress_tblspace
- tp_1_2    | tp_1_2_pkey | regress_tblspace
-(3 rows)
-
-DROP TABLE t;
--- Check new partitions inherits parent's table access method
-CREATE ACCESS METHOD partition_split_heap TYPE TABLE HANDLER heap_tableam_handler;
-CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partition_split_heap;
-CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-SELECT c.relname, a.amname
-FROM pg_class c JOIN pg_am a ON c.relam = a.oid
-WHERE c.oid IN ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass)
-ORDER BY c.relname;
- relname |        amname        
----------+----------------------
- t       | partition_split_heap
- tp_0_1  | partition_split_heap
- tp_1_2  | partition_split_heap
-(3 rows)
-
-DROP TABLE t;
-DROP ACCESS METHOD partition_split_heap;
--- Test permission checks.  The user needs to own the parent table and the
--- the partition to split to do the split.
-CREATE ROLE regress_partition_split_alice;
-CREATE ROLE regress_partition_split_bob;
-GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_alice;
-GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_bob;
-SET SESSION AUTHORIZATION regress_partition_split_alice;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-SET SESSION AUTHORIZATION regress_partition_split_bob;
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-ERROR:  must be owner of table t
-RESET SESSION AUTHORIZATION;
-ALTER TABLE t OWNER TO regress_partition_split_bob;
-SET SESSION AUTHORIZATION regress_partition_split_bob;
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-ERROR:  must be owner of table tp_0_2
-RESET SESSION AUTHORIZATION;
-ALTER TABLE tp_0_2 OWNER TO regress_partition_split_bob;
-SET SESSION AUTHORIZATION regress_partition_split_bob;
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-RESET SESSION AUTHORIZATION;
-DROP TABLE t;
-REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_alice;
-REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_bob;
-DROP ROLE regress_partition_split_alice;
-DROP ROLE regress_partition_split_bob;
--- Split partition of a temporary table when one of the partitions after
--- split has the same name as the partition being split
-CREATE TEMP TABLE t (a int) PARTITION BY RANGE (a);
-CREATE TEMP TABLE tp_0 PARTITION OF t FOR VALUES FROM (0) TO (2);
-ALTER TABLE t SPLIT PARTITION tp_0 INTO
-  (PARTITION tp_0 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1 FOR VALUES FROM (1) TO (2));
-DROP TABLE t;
-RESET search_path;
---
-DROP SCHEMA partition_split_schema;
-DROP SCHEMA partition_split_schema2;
index 2429ec2bbaab0f49cbe8923ab5eb9e696a0fbd58..f53a526f7cd948924b6f15739a3bb028f76e13bf 100644 (file)
@@ -119,7 +119,7 @@ test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion tr
 # The stats test resets stats, so nothing else needing stats access can be in
 # this group.
 # ----------
-test: partition_merge partition_split partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain compression memoize stats predicate
+test: partition_join partition_prune reloptions hash_part indexing partition_aggregate partition_info tuplesort explain compression memoize stats predicate
 
 # event_trigger depends on create_am and cannot run concurrently with
 # any test that runs DDL
diff --git a/src/test/regress/sql/partition_merge.sql b/src/test/regress/sql/partition_merge.sql
deleted file mode 100644 (file)
index bede819..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
---
--- PARTITIONS_MERGE
--- Tests for "ALTER TABLE ... MERGE PARTITIONS ..." command
---
-
-CREATE SCHEMA partitions_merge_schema;
-CREATE SCHEMA partitions_merge_schema2;
-SET search_path = partitions_merge_schema, public;
-
---
--- BY RANGE partitioning
---
-
---
--- Test for error codes
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_dec2021 PARTITION OF sales_range FOR VALUES FROM ('2021-12-01') TO ('2021-12-31');
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-
-CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_apr_1 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-15');
-CREATE TABLE sales_apr_2 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-15') TO ('2022-05-01');
-ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
--- ERROR:  partition with name "sales_feb2022" is already used
-ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_feb2022) INTO sales_feb_mar_apr2022;
--- ERROR:  "sales_apr2022" is not a table
-ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO sales_feb_mar_apr2022;
--- ERROR:  lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_jan2022"
--- (space between sections sales_jan2022 and sales_mar2022)
-ALTER TABLE sales_range MERGE PARTITIONS (sales_jan2022, sales_mar2022) INTO sales_jan_mar2022;
--- ERROR:  lower bound of partition "sales_jan2022" conflicts with upper bound of previous partition "sales_dec2021"
--- (space between sections sales_dec2021 and sales_jan2022)
-ALTER TABLE sales_range MERGE PARTITIONS (sales_dec2021, sales_jan2022, sales_feb2022) INTO sales_dec_jan_feb2022;
-
--- NO ERROR: test for custom partitions order, source partitions not in the search_path
-SET search_path = partitions_merge_schema2, public;
-ALTER TABLE partitions_merge_schema.sales_range MERGE PARTITIONS (
-  partitions_merge_schema.sales_feb2022,
-  partitions_merge_schema.sales_mar2022,
-  partitions_merge_schema.sales_jan2022) INTO sales_jan_feb_mar2022;
-SET search_path = partitions_merge_schema, public;
-
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-DROP TABLE sales_range;
-
---
--- Add rows into partitioned table, then merge partitions
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-SELECT pg_catalog.pg_get_partkeydef('sales_range'::regclass);
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
--- check schema-qualified name of the new partition
-ALTER TABLE sales_range MERGE PARTITIONS (sales_feb2022, sales_mar2022, sales_apr2022) INTO partitions_merge_schema2.sales_feb_mar_apr2022;
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_feb_mar_apr2022' and schemaname = 'partitions_merge_schema2';
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_jan2022;
-SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022;
-SELECT * FROM sales_others;
-
--- Use indexscan for testing indexes
-SET enable_seqscan = OFF;
-
-SELECT * FROM partitions_merge_schema2.sales_feb_mar_apr2022 where sales_date > '2022-01-01';
-
-RESET enable_seqscan;
-
-DROP TABLE sales_range;
-
---
--- Merge some partitions into DEFAULT partition
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-CREATE TABLE sales_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
--- Merge partitions (include DEFAULT partition) into partition with the same
--- name
-ALTER TABLE sales_range MERGE PARTITIONS
-  (sales_jan2022, sales_mar2022, partitions_merge_schema.sales_others) INTO sales_others;
-
-select * from sales_others;
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_range'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-DROP TABLE sales_range;
-
---
--- Test for:
---   * composite partition key;
---   * GENERATED column;
---   * column with DEFAULT value.
---
-CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT,
-  sales_date VARCHAR(10) GENERATED ALWAYS AS
-    (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED,
-  sales_department VARCHAR(30) DEFAULT 'Sales department')
-  PARTITION BY RANGE (sales_year, sales_month, sales_day);
-
-CREATE TABLE sales_dec2022 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1);
-CREATE TABLE sales_jan2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1);
-CREATE TABLE sales_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1);
-CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE);
-
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2021, 12, 7);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2021, 12, 8);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 1, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 2, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 1, 2);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 2, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 3, 3);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 3, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 5, 1);
-
-SELECT * FROM sales_date;
-SELECT * FROM sales_dec2022;
-SELECT * FROM sales_jan2022;
-SELECT * FROM sales_feb2022;
-SELECT * FROM sales_other;
-
-ALTER TABLE sales_date MERGE PARTITIONS (sales_jan2022, sales_feb2022) INTO sales_jan_feb2022;
-
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 1, 10);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 2, 10);
-
-SELECT * FROM sales_date;
-SELECT * FROM sales_dec2022;
-SELECT * FROM sales_jan_feb2022;
-SELECT * FROM sales_other;
-
-DROP TABLE sales_date;
-
---
--- Test: merge partitions of partitioned table with triggers
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
-CREATE TABLE salespeople10_20 PARTITION OF salespeople FOR VALUES FROM (10) TO (20);
-CREATE TABLE salespeople20_30 PARTITION OF salespeople FOR VALUES FROM (20) TO (30);
-CREATE TABLE salespeople30_40 PARTITION OF salespeople FOR VALUES FROM (30) TO (40);
-
-INSERT INTO salespeople VALUES (1,  'Poirot');
-
-CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$
-BEGIN
-   RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;
-    RETURN NULL;
-END;
-$BODY$;
-
-CREATE TRIGGER salespeople_after_insert_statement_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH STATEMENT
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
-
-CREATE TRIGGER salespeople_after_insert_row_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH ROW
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
-
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (10, 'May');
--- 1 trigger should fire here (row):
-INSERT INTO salespeople10_20 VALUES (19, 'Ivanov');
-
-ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40;
-
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (20, 'Smirnoff');
--- 1 trigger should fire here (row):
-INSERT INTO salespeople10_40 VALUES (30, 'Ford');
-
-SELECT * FROM salespeople01_10;
-SELECT * FROM salespeople10_40;
-
-DROP TABLE salespeople;
-DROP FUNCTION after_insert_row_trigger();
-
---
--- Test: merge partitions with deleted columns
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
--- Create partitions with some deleted columns:
-CREATE TABLE salespeople10_20(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30));
-CREATE TABLE salespeople20_30(salesperson_id INT PRIMARY KEY, d2 INT,  salesperson_name VARCHAR(30));
-CREATE TABLE salespeople30_40(salesperson_id INT PRIMARY KEY, d3 DATE, salesperson_name VARCHAR(30));
-
-INSERT INTO salespeople10_20 VALUES ('dummy value 1', 19, 'Ivanov');
-INSERT INTO salespeople20_30 VALUES (20, 101, 'Smirnoff');
-INSERT INTO salespeople30_40 VALUES (31, now(), 'Popov');
-
-ALTER TABLE salespeople10_20 DROP COLUMN d1;
-ALTER TABLE salespeople20_30 DROP COLUMN d2;
-ALTER TABLE salespeople30_40 DROP COLUMN d3;
-
-ALTER TABLE salespeople ATTACH PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20);
-ALTER TABLE salespeople ATTACH PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30);
-ALTER TABLE salespeople ATTACH PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40);
-
-INSERT INTO salespeople VALUES (1, 'Poirot');
-INSERT INTO salespeople VALUES (10, 'May');
-INSERT INTO salespeople VALUES (30, 'Ford');
-
-ALTER TABLE salespeople MERGE PARTITIONS (salespeople10_20, salespeople20_30, salespeople30_40) INTO salespeople10_40;
-
-select * from salespeople;
-select * from salespeople01_10;
-select * from salespeople10_40;
-
-DROP TABLE salespeople;
-
---
--- Test: merge sub-partitions
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-
-CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_apr2022_01_10 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10');
-CREATE TABLE sales_apr2022_10_20 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20');
-CREATE TABLE sales_apr2022_20_30 PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01');
-ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_apr2022;
-SELECT * FROM sales_apr2022_01_10;
-SELECT * FROM sales_apr2022_10_20;
-SELECT * FROM sales_apr2022_20_30;
-
-ALTER TABLE sales_apr2022 MERGE PARTITIONS (sales_apr2022_01_10, sales_apr2022_10_20, sales_apr2022_20_30) INTO sales_apr_all;
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_apr2022;
-SELECT * FROM sales_apr_all;
-
-DROP TABLE sales_range;
-
---
--- BY LIST partitioning
---
-
---
--- Test: specific errors for BY LIST partitioning
---
-CREATE TABLE sales_list
-(salesperson_id INT GENERATED ALWAYS AS IDENTITY,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid');
-CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok');
-CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-
-
-CREATE TABLE sales_list2 (LIKE sales_list) PARTITION BY LIST (sales_state);
-CREATE TABLE sales_nord2 PARTITION OF sales_list2 FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_others2 PARTITION OF sales_list2 DEFAULT;
-
-
-CREATE TABLE sales_external (LIKE sales_list);
-CREATE TABLE sales_external2 (vch VARCHAR(5));
-
--- ERROR:  "sales_external" is not a partition
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external) INTO sales_all;
--- ERROR:  "sales_external2" is not a partition
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_external2) INTO sales_all;
--- ERROR:  relation "sales_nord2" is not a partition of relation "sales_list"
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_nord2, sales_east) INTO sales_all;
-
-DROP TABLE sales_external2;
-DROP TABLE sales_external;
-DROP TABLE sales_list2;
-DROP TABLE sales_list;
-
---
--- Test: BY LIST partitioning, MERGE PARTITIONS with data
---
-CREATE TABLE sales_list
-(salesperson_id INT GENERATED ALWAYS AS IDENTITY,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-
-CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name);
-CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state);
-
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_west PARTITION OF sales_list FOR VALUES IN ('Lisbon', 'New York', 'Madrid');
-CREATE TABLE sales_east PARTITION OF sales_list FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok');
-CREATE TABLE sales_central PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Trump',    'Bejing',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smirnoff', 'New York',        500, '2022-03-03');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ford',     'St. Petersburg', 2000, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ivanov',   'Warsaw',          750, '2022-03-04');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Deev',     'Lisbon',          250, '2022-03-07');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Poirot',   'Berlin',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Helsinki',       1200, '2022-03-06');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Li',       'Vladivostok',    1150, '2022-03-09');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Helsinki',       1200, '2022-03-11');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Halder',   'Oslo',            800, '2022-03-02');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Muller',   'Madrid',          650, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smith',    'Kyiv',            350, '2022-03-10');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Gandi',    'Warsaw',          150, '2022-03-08');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Plato',    'Lisbon',          950, '2022-03-05');
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_list'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-ALTER TABLE sales_list MERGE PARTITIONS (sales_west, sales_east, sales_central) INTO sales_all;
-
--- show partitions with conditions:
-SELECT c.oid::pg_catalog.regclass, c.relkind, inhdetachpending, pg_catalog.pg_get_expr(c.relpartbound, c.oid)
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 'sales_list'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-SELECT * FROM sales_list;
-SELECT * FROM sales_nord;
-SELECT * FROM sales_all;
-
--- Use indexscan for testing indexes after merging partitions
-SET enable_seqscan = OFF;
-
-SELECT * FROM sales_all WHERE sales_state = 'Warsaw';
-SELECT * FROM sales_list WHERE sales_state = 'Warsaw';
-SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov';
-
-RESET enable_seqscan;
-
-DROP TABLE sales_list;
-
---
--- Try to MERGE partitions of another table.
---
-CREATE TABLE t1 (i int, a int, b int, c int) PARTITION BY RANGE (a, b);
-CREATE TABLE t1p1 PARTITION OF t1 FOR VALUES FROM (1, 1) TO (1, 2);
-CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t);
-CREATE TABLE t2pa PARTITION OF t2 FOR VALUES FROM ('A') TO ('C');
-CREATE TABLE t3 (i int, t text);
-
--- ERROR:  relation "t1p1" is not a partition of relation "t2"
-ALTER TABLE t2 MERGE PARTITIONS (t1p1, t2pa) INTO t2p;
--- ERROR:  "t3" is not a partition
-ALTER TABLE t2 MERGE PARTITIONS (t2pa, t3) INTO t2p;
-
-DROP TABLE t3;
-DROP TABLE t2;
-DROP TABLE t1;
-
---
--- Try to MERGE partitions of temporary table.
---
-CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TEMP TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TEMP TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-
--- Partition should be temporary.
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-DROP TABLE t;
-
---
--- Check the partition index name if the partition name is the same as one
--- of the merged partitions.
---
-CREATE TABLE t (i int, PRIMARY KEY(i)) PARTITION BY RANGE (i);
-
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-
-CREATE INDEX tidx ON t(i);
-ALTER TABLE t MERGE PARTITIONS (tp_1_2, tp_0_1) INTO tp_1_2;
-
--- Indexname values should be 'tp_1_2_pkey' and 'tp_1_2_i_idx'.
--- Not-null constraint name should be 'tp_1_2_i_not_null'.
-\d+ tp_1_2
-
-DROP TABLE t;
-
---
--- Try mixing permanent and temporary partitions.
---
-SET search_path = partitions_merge_schema, pg_temp, public;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-
-SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-SET search_path = pg_temp, partitions_merge_schema, public;
-
--- Can't merge persistent partitions into a temporary partition
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-
-SET search_path = partitions_merge_schema, public;
-
--- Can't merge persistent partitions into a temporary partition
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO pg_temp.tp_0_2;
-DROP TABLE t;
-
-SET search_path = pg_temp, partitions_merge_schema, public;
-
-BEGIN;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-
-SELECT c.oid::pg_catalog.regclass, c.relpersistence FROM pg_catalog.pg_class c WHERE c.oid = 't'::regclass;
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-SET search_path = partitions_merge_schema, pg_temp, public;
-
--- Can't merge temporary partitions into a persistent partition
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-ROLLBACK;
-
--- Check the new partition inherits parent's tablespace
-SET search_path = partitions_merge_schema, public;
-CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace)
-  PARTITION BY RANGE (i) TABLESPACE regress_tblspace;
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-SELECT tablename, tablespace FROM pg_tables
-  WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema'
-  ORDER BY tablename, tablespace;
-SELECT tablename, indexname, tablespace FROM pg_indexes
-  WHERE tablename IN ('t', 'tp_0_2') AND schemaname = 'partitions_merge_schema'
-  ORDER BY tablename, indexname, tablespace;
-DROP TABLE t;
-
--- Check the new partition inherits parent's table access method
-SET search_path = partitions_merge_schema, public;
-CREATE ACCESS METHOD partitions_merge_heap TYPE TABLE HANDLER heap_tableam_handler;
-CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partitions_merge_heap;
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-SELECT c.relname, a.amname
-FROM pg_class c JOIN pg_am a ON c.relam = a.oid
-WHERE c.oid IN ('t'::regclass, 'tp_0_2'::regclass)
-ORDER BY c.relname;
-DROP TABLE t;
-DROP ACCESS METHOD partitions_merge_heap;
-
--- Test permission checks.  The user needs to own the parent table and all
--- the merging partitions to do the merge.
-CREATE ROLE regress_partition_merge_alice;
-CREATE ROLE regress_partition_merge_bob;
-GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_alice;
-GRANT ALL ON SCHEMA partitions_merge_schema TO regress_partition_merge_bob;
-
-SET SESSION AUTHORIZATION regress_partition_merge_alice;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_1 PARTITION OF t FOR VALUES FROM (0) TO (1);
-CREATE TABLE tp_1_2 PARTITION OF t FOR VALUES FROM (1) TO (2);
-
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-RESET SESSION AUTHORIZATION;
-
-ALTER TABLE t OWNER TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-RESET SESSION AUTHORIZATION;
-
-ALTER TABLE tp_0_1 OWNER TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-RESET SESSION AUTHORIZATION;
-
-ALTER TABLE tp_1_2 OWNER TO regress_partition_merge_bob;
-SET SESSION AUTHORIZATION regress_partition_merge_bob;
-ALTER TABLE t MERGE PARTITIONS (tp_0_1, tp_1_2) INTO tp_0_2;
-RESET SESSION AUTHORIZATION;
-
-DROP TABLE t;
-REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_alice;
-REVOKE ALL ON SCHEMA partitions_merge_schema FROM regress_partition_merge_bob;
-DROP ROLE regress_partition_merge_alice;
-DROP ROLE regress_partition_merge_bob;
-
-RESET search_path;
-
---
-DROP SCHEMA partitions_merge_schema;
-DROP SCHEMA partitions_merge_schema2;
diff --git a/src/test/regress/sql/partition_split.sql b/src/test/regress/sql/partition_split.sql
deleted file mode 100644 (file)
index ef5ea07..0000000
+++ /dev/null
@@ -1,962 +0,0 @@
---
--- PARTITION_SPLIT
--- Tests for "ALTER TABLE ... SPLIT PARTITION ..." command
---
-
-CREATE SCHEMA partition_split_schema;
-CREATE SCHEMA partition_split_schema2;
-SET search_path = partition_split_schema, public;
-
---
--- BY RANGE partitioning
---
-
---
--- Test for error codes
---
-CREATE TABLE sales_range (salesperson_id int, salesperson_name varchar(30), sales_amount int, sales_date date) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
--- ERROR:  relation "sales_xxx" does not exist
-ALTER TABLE sales_range SPLIT PARTITION sales_xxx INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  relation "sales_jan2022" already exists
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  invalid bound specification for a range partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES IN ('2022-05-01', '2022-06-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  empty range bound specified for partition "sales_mar2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-02-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
---ERROR:  list of split partitions should contain at least two items
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-10-01'));
-
--- ERROR:  lower bound of partition "sales_feb2022" is less than lower bound of split partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-01-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  name "sales_feb_mar_apr2022" is already used
--- (We can create partition with the same name as split partition, but can't create two partitions with the same name)
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_feb_mar_apr2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  name "sales_feb2022" is already used
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  "sales_feb_mar_apr2022" is not a partitioned table
-ALTER TABLE sales_feb_mar_apr2022 SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_feb2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- ERROR:  upper bound of partition "sales_apr2022" is greater than upper bound of split partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-06-01'));
-
--- ERROR:  lower bound of partition "sales_mar2022" conflicts with upper bound of previous partition "sales_feb2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-02-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- Tests for spaces between partitions, them should be executed without DEFAULT partition
-ALTER TABLE sales_range DETACH PARTITION sales_others;
-
--- ERROR:  lower bound of partition "sales_feb2022" is not equal to lower bound of split partition
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-02') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- Check the source partition not in the search path
-SET search_path = partition_split_schema2, public;
-ALTER TABLE partition_split_schema.sales_range
-SPLIT PARTITION partition_split_schema.sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-SET search_path = partition_split_schema, public;
-\d+ sales_range
-
-DROP TABLE sales_range;
-DROP TABLE sales_others;
-
---
--- Add rows into partitioned table then split partition
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_jan2022;
-SELECT * FROM sales_feb2022;
-SELECT * FROM sales_mar2022;
-SELECT * FROM sales_apr2022;
-SELECT * FROM sales_others;
-
-DROP TABLE sales_range CASCADE;
-
---
--- Add split partition, then add rows into partitioned table
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
--- Split partition, also check schema qualification of new partitions
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION partition_split_schema.sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION partition_split_schema2.sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-\d+ sales_range
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_jan2022;
-SELECT * FROM sales_feb2022;
-SELECT * FROM partition_split_schema2.sales_mar2022;
-SELECT * FROM sales_apr2022;
-SELECT * FROM sales_others;
-
-DROP TABLE sales_range CASCADE;
-
---
--- Test for:
---   * composite partition key;
---   * GENERATED column;
---   * column with DEFAULT value.
---
-CREATE TABLE sales_date (salesperson_name VARCHAR(30), sales_year INT, sales_month INT, sales_day INT,
-  sales_date VARCHAR(10) GENERATED ALWAYS AS
-    (LPAD(sales_year::text, 4, '0') || '.' || LPAD(sales_month::text, 2, '0') || '.' || LPAD(sales_day::text, 2, '0')) STORED,
-  sales_department VARCHAR(30) DEFAULT 'Sales department')
-  PARTITION BY RANGE (sales_year, sales_month, sales_day);
-
-CREATE TABLE sales_dec2022 PARTITION OF sales_date FOR VALUES FROM (2021, 12, 1) TO (2022, 1, 1);
-CREATE TABLE sales_jan_feb2022 PARTITION OF sales_date FOR VALUES FROM (2022, 1, 1) TO (2022, 3, 1);
-CREATE TABLE sales_other PARTITION OF sales_date FOR VALUES FROM (2022, 3, 1) TO (MAXVALUE, MAXVALUE, MAXVALUE);
-
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2021, 12, 7);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2021, 12, 8);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 1, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 2, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 1, 2);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 2, 1);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 3, 3);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 3, 4);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager3', 2022, 5, 1);
-
-SELECT * FROM sales_date;
-SELECT * FROM sales_dec2022;
-SELECT * FROM sales_jan_feb2022;
-SELECT * FROM sales_other;
-
-ALTER TABLE sales_date SPLIT PARTITION sales_jan_feb2022 INTO
-  (PARTITION sales_jan2022 FOR VALUES FROM (2022, 1, 1) TO (2022, 2, 1),
-   PARTITION sales_feb2022 FOR VALUES FROM (2022, 2, 1) TO (2022, 3, 1));
-
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager1', 2022, 1, 10);
-INSERT INTO sales_date(salesperson_name, sales_year, sales_month, sales_day) VALUES ('Manager2', 2022, 2, 10);
-
-SELECT * FROM sales_date;
-SELECT * FROM sales_dec2022;
-SELECT * FROM sales_jan2022;
-SELECT * FROM sales_feb2022;
-SELECT * FROM sales_other;
-
---ERROR:  relation "sales_jan_feb2022" does not exist
-SELECT * FROM sales_jan_feb2022;
-
-DROP TABLE sales_date CASCADE;
-
---
--- Test: split DEFAULT partition; use an index on partition key; check index after split
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-SELECT * FROM sales_others;
-SELECT * FROM pg_indexes WHERE tablename = 'sales_others' and schemaname = 'partition_split_schema' ORDER BY indexname;
-
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'),
-   PARTITION sales_others DEFAULT);
-
--- Use indexscan for testing indexes
-SET enable_indexscan = ON;
-SET enable_seqscan = OFF;
-
-SELECT * FROM sales_feb2022 where sales_date > '2022-01-01';
-SELECT * FROM sales_mar2022 where sales_date > '2022-01-01';
-SELECT * FROM sales_apr2022 where sales_date > '2022-01-01';
-SELECT * FROM sales_others where sales_date > '2022-01-01';
-
-SET enable_indexscan = ON;
-SET enable_seqscan = ON;
-
-SELECT * FROM pg_indexes WHERE tablename = 'sales_feb2022' and schemaname = 'partition_split_schema' ORDER BY indexname;
-SELECT * FROM pg_indexes WHERE tablename = 'sales_mar2022' and schemaname = 'partition_split_schema' ORDER BY indexname;
-SELECT * FROM pg_indexes WHERE tablename = 'sales_apr2022' and schemaname = 'partition_split_schema' ORDER BY indexname;
-SELECT * FROM pg_indexes WHERE tablename = 'sales_others' and schemaname = 'partition_split_schema' ORDER BY indexname;
-
-DROP TABLE sales_range CASCADE;
-
---
--- Test: some cases for splitting DEFAULT partition (different bounds)
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date INT) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
--- sales_error intersects with sales_dec2022 (lower bound)
--- ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20211230) TO (20220201),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-
--- sales_error intersects with sales_feb2022 (upper bound)
--- ERROR:  lower bound of partition "sales_feb2022" conflicts with upper bound of previous partition "sales_error"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20220101) TO (20220202),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-
--- sales_error intersects with sales_dec2022 (inside bound)
--- ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20211210) TO (20211220),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-
--- sales_error intersects with sales_dec2022 (exactly the same bounds)
--- ERROR:  lower bound of partition "sales_error" conflicts with upper bound of previous partition "sales_dec2022"
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_error FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-
--- ERROR:  all partitions in the list should be DEFAULT because split partition is DEFAULT
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_jan2022 FOR VALUES FROM (20220101) TO (20220201),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301));
-
--- no error: bounds of sales_noerror are between sales_dec2022 and sales_feb2022
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_noerror FOR VALUES FROM (20220110) TO (20220120),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-
-DROP TABLE sales_range;
-
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date INT) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
--- no error: bounds of sales_noerror are equal to lower and upper bounds of sales_dec2022 and sales_feb2022
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_dec2022 FOR VALUES FROM (20211201) TO (20220101),
-   PARTITION sales_noerror FOR VALUES FROM (20210101) TO (20210201),
-   PARTITION sales_feb2022 FOR VALUES FROM (20220201) TO (20220301),
-   PARTITION sales_others DEFAULT);
-
-DROP TABLE sales_range;
-
---
--- Test: split partition with CHECK and FOREIGN KEY CONSTRAINTs on partitioned table
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30));
-INSERT INTO salespeople VALUES (1,  'Poirot');
-
-CREATE TABLE sales_range (
-salesperson_id INT REFERENCES salespeople(salesperson_id),
-sales_amount INT CHECK (sales_amount > 1),
-sales_date DATE) PARTITION BY RANGE (sales_date);
-
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb_mar_apr2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb_mar_apr2022'::regclass::oid ORDER BY conname;
-
-ALTER TABLE sales_range SPLIT PARTITION sales_feb_mar_apr2022 INTO
-  (PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_mar2022 FOR VALUES FROM ('2022-03-01') TO ('2022-04-01'),
-   PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'));
-
--- We should see the same CONSTRAINTs as on sales_feb_mar_apr2022 partition
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_feb2022'::regclass::oid ORDER BY conname;;
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_mar2022'::regclass::oid ORDER BY conname;;
-SELECT pg_get_constraintdef(oid), conname, conkey FROM pg_constraint WHERE conrelid = 'sales_apr2022'::regclass::oid ORDER BY conname;;
-
--- ERROR:  new row for relation "sales_mar2022" violates check constraint "sales_range_sales_amount_check"
-INSERT INTO sales_range VALUES (1, 0, '2022-03-11');
--- ERROR:  insert or update on table "sales_mar2022" violates foreign key constraint "sales_range_salesperson_id_fkey"
-INSERT INTO sales_range VALUES (-1, 10, '2022-03-11');
--- ok
-INSERT INTO sales_range VALUES (1, 10, '2022-03-11');
-
-DROP TABLE sales_range CASCADE;
-DROP TABLE salespeople CASCADE;
-
---
--- Test: split partition on partitioned table in case of existing FOREIGN KEY reference from another table
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-CREATE TABLE sales (salesperson_id INT REFERENCES salespeople(salesperson_id), sales_amount INT, sales_date DATE);
-
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
-CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40);
-
-INSERT INTO salespeople VALUES (1,  'Poirot');
-INSERT INTO salespeople VALUES (10, 'May');
-INSERT INTO salespeople VALUES (19, 'Ivanov');
-INSERT INTO salespeople VALUES (20, 'Smirnoff');
-INSERT INTO salespeople VALUES (30, 'Ford');
-
-INSERT INTO sales VALUES (1,  100, '2022-03-01');
-INSERT INTO sales VALUES (1,  110, '2022-03-02');
-INSERT INTO sales VALUES (10, 150, '2022-03-01');
-INSERT INTO sales VALUES (10, 90,  '2022-03-03');
-INSERT INTO sales VALUES (19, 200, '2022-03-04');
-INSERT INTO sales VALUES (20, 50,  '2022-03-12');
-INSERT INTO sales VALUES (20, 170, '2022-03-02');
-INSERT INTO sales VALUES (30, 30,  '2022-03-04');
-
-SELECT * FROM salespeople01_10;
-SELECT * FROM salespeople10_40;
-
-ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO
-  (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20),
-   PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30),
-   PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40));
-
-SELECT * FROM salespeople01_10;
-SELECT * FROM salespeople10_20;
-SELECT * FROM salespeople20_30;
-SELECT * FROM salespeople30_40;
-
--- ERROR:  insert or update on table "sales" violates foreign key constraint "sales_salesperson_id_fkey"
-INSERT INTO sales VALUES (40, 50,  '2022-03-04');
--- ok
-INSERT INTO sales VALUES (30, 50,  '2022-03-04');
-
-DROP TABLE sales CASCADE;
-DROP TABLE salespeople CASCADE;
-
---
--- Test: split partition of partitioned table with triggers
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
-CREATE TABLE salespeople10_40 PARTITION OF salespeople FOR VALUES FROM (10) TO (40);
-
-INSERT INTO salespeople VALUES (1,  'Poirot');
-
-CREATE OR REPLACE FUNCTION after_insert_row_trigger() RETURNS trigger LANGUAGE 'plpgsql' AS $BODY$
-BEGIN
-   RAISE NOTICE 'trigger(%) called: action = %, when = %, level = %', TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL;
-    RETURN NULL;
-END;
-$BODY$;
-
-CREATE TRIGGER salespeople_after_insert_statement_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH STATEMENT
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
-
-CREATE TRIGGER salespeople_after_insert_row_trigger
-    AFTER INSERT
-    ON salespeople
-    FOR EACH ROW
-    EXECUTE PROCEDURE after_insert_row_trigger('salespeople');
-
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (10, 'May');
--- 1 trigger should fire here (row):
-INSERT INTO salespeople10_40 VALUES (19, 'Ivanov');
-
-ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO
-  (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20),
-   PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30),
-   PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40));
-
--- 2 triggers should fire here (row + statement):
-INSERT INTO salespeople VALUES (20, 'Smirnoff');
--- 1 trigger should fire here (row):
-INSERT INTO salespeople30_40 VALUES (30, 'Ford');
-
-SELECT * FROM salespeople01_10;
-SELECT * FROM salespeople10_20;
-SELECT * FROM salespeople20_30;
-SELECT * FROM salespeople30_40;
-
-DROP TABLE salespeople CASCADE;
-DROP FUNCTION after_insert_row_trigger();
-
---
--- Test: split partition witch identity column
--- If split partition column is identity column, columns of new partitions are identity columns too.
---
-CREATE TABLE salespeople(salesperson_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-
-CREATE TABLE salespeople1_2 PARTITION OF salespeople FOR VALUES FROM (1) TO (2);
--- Create new partition with identity column:
-CREATE TABLE salespeople2_5(salesperson_id INT NOT NULL, salesperson_name VARCHAR(30));
-ALTER TABLE salespeople ATTACH PARTITION salespeople2_5 FOR VALUES FROM (2) TO (5);
-
-INSERT INTO salespeople (salesperson_name) VALUES ('Poirot');
-INSERT INTO salespeople (salesperson_name) VALUES ('Ivanov');
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople'::regclass::oid ORDER BY attnum;
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople1_2'::regclass::oid ORDER BY attnum;
--- Split partition has identity column:
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople2_5'::regclass::oid ORDER BY attnum;
-
-ALTER TABLE salespeople SPLIT PARTITION salespeople2_5 INTO
-  (PARTITION salespeople2_3 FOR VALUES FROM (2) TO (3),
-   PARTITION salespeople3_4 FOR VALUES FROM (3) TO (4),
-   PARTITION salespeople4_5 FOR VALUES FROM (4) TO (5));
-
-INSERT INTO salespeople (salesperson_name) VALUES ('May');
-INSERT INTO salespeople (salesperson_name) VALUES ('Ford');
-
-SELECT * FROM salespeople1_2;
-SELECT * FROM salespeople2_3;
-SELECT * FROM salespeople3_4;
-SELECT * FROM salespeople4_5;
-
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople'::regclass::oid ORDER BY attnum;
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople1_2'::regclass::oid ORDER BY attnum;
--- New partitions have identity-columns:
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople2_3'::regclass::oid ORDER BY attnum;
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople3_4'::regclass::oid ORDER BY attnum;
-SELECT attname, attidentity, attgenerated FROM pg_attribute WHERE attnum > 0 AND attrelid = 'salespeople4_5'::regclass::oid ORDER BY attnum;
-
-DROP TABLE salespeople CASCADE;
-
---
--- Test: split partition with deleted columns
---
-CREATE TABLE salespeople(salesperson_id INT PRIMARY KEY, salesperson_name VARCHAR(30)) PARTITION BY RANGE (salesperson_id);
-
-CREATE TABLE salespeople01_10 PARTITION OF salespeople FOR VALUES FROM (1) TO (10);
--- Create new partition with some deleted columns:
-CREATE TABLE salespeople10_40(d1 VARCHAR(30), salesperson_id INT PRIMARY KEY, d2 INT, d3 DATE, salesperson_name VARCHAR(30));
-
-INSERT INTO salespeople10_40 VALUES ('dummy value 1', 19, 100, now(), 'Ivanov');
-INSERT INTO salespeople10_40 VALUES ('dummy value 2', 20, 101, now(), 'Smirnoff');
-
-ALTER TABLE salespeople10_40 DROP COLUMN d1;
-ALTER TABLE salespeople10_40 DROP COLUMN d2;
-ALTER TABLE salespeople10_40 DROP COLUMN d3;
-
-ALTER TABLE salespeople ATTACH PARTITION salespeople10_40 FOR VALUES FROM (10) TO (40);
-
-INSERT INTO salespeople VALUES (1, 'Poirot');
-INSERT INTO salespeople VALUES (10, 'May');
-INSERT INTO salespeople VALUES (30, 'Ford');
-
-ALTER TABLE salespeople SPLIT PARTITION salespeople10_40 INTO
-  (PARTITION salespeople10_20 FOR VALUES FROM (10) TO (20),
-   PARTITION salespeople20_30 FOR VALUES FROM (20) TO (30),
-   PARTITION salespeople30_40 FOR VALUES FROM (30) TO (40));
-
-select * from salespeople01_10;
-select * from salespeople10_20;
-select * from salespeople20_30;
-select * from salespeople30_40;
-
-DROP TABLE salespeople CASCADE;
-
---
--- Test: split sub-partition
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_feb2022 PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-03-01');
-CREATE TABLE sales_mar2022 PARTITION OF sales_range FOR VALUES FROM ('2022-03-01') TO ('2022-04-01');
-
-CREATE TABLE sales_apr2022 (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_apr_all PARTITION OF sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-ALTER TABLE sales_range ATTACH PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01');
-
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
-CREATE INDEX sales_range_sales_date_idx ON sales_range USING btree (sales_date);
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_apr2022;
-
-ALTER TABLE sales_apr2022 SPLIT PARTITION sales_apr_all INTO
-  (PARTITION sales_apr2022_01_10 FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'),
-   PARTITION sales_apr2022_10_20 FOR VALUES FROM ('2022-04-10') TO ('2022-04-20'),
-   PARTITION sales_apr2022_20_30 FOR VALUES FROM ('2022-04-20') TO ('2022-05-01'));
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_apr2022;
-SELECT * FROM sales_apr2022_01_10;
-SELECT * FROM sales_apr2022_10_20;
-SELECT * FROM sales_apr2022_20_30;
-
-DROP TABLE sales_range;
-
---
--- BY LIST partitioning
---
-
---
--- Test: specific errors for BY LIST partitioning
---
-CREATE TABLE sales_list
-(salesperson_id INT,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Oslo', 'St. Petersburg', 'Helsinki');
-CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Bejing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-
--- ERROR:  new partition "sales_east" would overlap with another (not split) partition "sales_nord"
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok', 'Helsinki'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-
--- ERROR:  new partition "sales_west" would overlap with another new partition "sales_central"
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Lisbon', 'Kyiv'));
-
--- ERROR:  new partition "sales_west" cannot have NULL value because split partition does not have
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid', NULL),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-
-DROP TABLE sales_list;
-
---
--- Test: two specific errors for BY LIST partitioning:
---   * new partitions do not have NULL value, which split partition has.
---   * new partitions do not have a value that split partition has.
---
-CREATE TABLE sales_list
-(salesperson_id INT,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo');
-CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Bejing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok', NULL);
-
--- ERROR:  new partitions do not have value NULL but split partition does
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-
--- ERROR:  new partitions do not have value 'Kyiv' but split partition does
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', NULL));
-
-DROP TABLE sales_list;
-
---
--- Test: BY LIST partitioning, SPLIT PARTITION with data
---
-CREATE TABLE sales_list
-(salesperson_id SERIAL,
- salesperson_name VARCHAR(30),
- sales_state VARCHAR(20),
- sales_amount INT,
- sales_date DATE)
-PARTITION BY LIST (sales_state);
-
-CREATE INDEX sales_list_salesperson_name_idx ON sales_list USING btree (salesperson_name);
-CREATE INDEX sales_list_sales_state_idx ON sales_list USING btree (sales_state);
-
-CREATE TABLE sales_nord PARTITION OF sales_list FOR VALUES IN ('Helsinki', 'St. Petersburg', 'Oslo');
-CREATE TABLE sales_all PARTITION OF sales_list FOR VALUES IN ('Warsaw', 'Lisbon', 'New York', 'Madrid', 'Bejing', 'Berlin', 'Delhi', 'Kyiv', 'Vladivostok');
-CREATE TABLE sales_others PARTITION OF sales_list DEFAULT;
-
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Trump',    'Bejing',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smirnoff', 'New York',        500, '2022-03-03');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ford',     'St. Petersburg', 2000, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Ivanov',   'Warsaw',          750, '2022-03-04');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Deev',     'Lisbon',          250, '2022-03-07');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Poirot',   'Berlin',         1000, '2022-03-01');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Oslo',           1200, '2022-03-06');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Li',       'Vladivostok',    1150, '2022-03-09');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('May',      'Oslo',           1200, '2022-03-11');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Halder',   'Helsinki',        800, '2022-03-02');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Muller',   'Madrid',          650, '2022-03-05');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Smith',    'Kyiv',            350, '2022-03-10');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Gandi',    'Warsaw',          150, '2022-03-08');
-INSERT INTO sales_list (salesperson_name, sales_state, sales_amount, sales_date) VALUES ('Plato',    'Lisbon',          950, '2022-03-05');
-
-ALTER TABLE sales_list SPLIT PARTITION sales_all INTO
-  (PARTITION sales_west FOR VALUES IN ('Lisbon', 'New York', 'Madrid'),
-   PARTITION sales_east FOR VALUES IN ('Bejing', 'Delhi', 'Vladivostok'),
-   PARTITION sales_central FOR VALUES IN ('Warsaw', 'Berlin', 'Kyiv'));
-
-SELECT * FROM sales_list;
-SELECT * FROM sales_west;
-SELECT * FROM sales_east;
-SELECT * FROM sales_nord;
-SELECT * FROM sales_central;
-
--- Use indexscan for testing indexes after splitting partition
-SET enable_indexscan = ON;
-SET enable_seqscan = OFF;
-
-SELECT * FROM sales_central WHERE sales_state = 'Warsaw';
-SELECT * FROM sales_list WHERE sales_state = 'Warsaw';
-SELECT * FROM sales_list WHERE salesperson_name = 'Ivanov';
-
-SET enable_indexscan = ON;
-SET enable_seqscan = ON;
-
-DROP TABLE sales_list;
-
---
--- Test for:
---   * split DEFAULT partition to partitions with spaces between bounds;
---   * random order of partitions in SPLIT PARTITION command.
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-09');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-07');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-ALTER TABLE sales_range SPLIT PARTITION sales_others INTO
-  (PARTITION sales_others DEFAULT,
-   PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'),
-   PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'),
-   PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'),
-   PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'));
-
-SELECT * FROM sales_jan2022_1decade;
-SELECT * FROM sales_feb2022_1decade;
-SELECT * FROM sales_mar2022_1decade;
-SELECT * FROM sales_apr2022_1decade;
-SELECT * FROM sales_others;
-
-DROP TABLE sales_range;
-
---
--- Test for:
---   * split non-DEFAULT partition to partitions with spaces between bounds;
---   * random order of partitions in SPLIT PARTITION command.
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-05-01');
-CREATE TABLE sales_others PARTITION OF sales_range DEFAULT;
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-09');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-07');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-ALTER TABLE sales_range SPLIT PARTITION sales_all INTO
-  (PARTITION sales_mar2022_1decade FOR VALUES FROM ('2022-03-01') TO ('2022-03-10'),
-   PARTITION sales_jan2022_1decade FOR VALUES FROM ('2022-01-01') TO ('2022-01-10'),
-   PARTITION sales_feb2022_1decade FOR VALUES FROM ('2022-02-01') TO ('2022-02-10'),
-   PARTITION sales_apr2022_1decade FOR VALUES FROM ('2022-04-01') TO ('2022-04-10'));
-
-SELECT * FROM sales_jan2022_1decade;
-SELECT * FROM sales_feb2022_1decade;
-SELECT * FROM sales_mar2022_1decade;
-SELECT * FROM sales_apr2022_1decade;
-SELECT * FROM sales_others;
-
-DROP TABLE sales_range;
-
---
--- Test for split non-DEFAULT partition to DEFAULT partition + partitions
--- with spaces between bounds.
---
-CREATE TABLE sales_range (salesperson_id INT, salesperson_name VARCHAR(30), sales_amount INT, sales_date DATE) PARTITION BY RANGE (sales_date);
-CREATE TABLE sales_jan2022 PARTITION OF sales_range FOR VALUES FROM ('2022-01-01') TO ('2022-02-01');
-CREATE TABLE sales_all PARTITION OF sales_range FOR VALUES FROM ('2022-02-01') TO ('2022-05-01');
-
-INSERT INTO sales_range VALUES (1,  'May',      1000, '2022-01-31');
-INSERT INTO sales_range VALUES (2,  'Smirnoff', 500,  '2022-02-10');
-INSERT INTO sales_range VALUES (3,  'Ford',     2000, '2022-04-30');
-INSERT INTO sales_range VALUES (4,  'Ivanov',   750,  '2022-04-13');
-INSERT INTO sales_range VALUES (5,  'Deev',     250,  '2022-04-07');
-INSERT INTO sales_range VALUES (6,  'Poirot',   150,  '2022-02-11');
-INSERT INTO sales_range VALUES (7,  'Li',       175,  '2022-03-08');
-INSERT INTO sales_range VALUES (8,  'Ericsson', 185,  '2022-02-23');
-INSERT INTO sales_range VALUES (9,  'Muller',   250,  '2022-03-11');
-INSERT INTO sales_range VALUES (10, 'Halder',   350,  '2022-01-28');
-INSERT INTO sales_range VALUES (11, 'Trump',    380,  '2022-04-06');
-INSERT INTO sales_range VALUES (12, 'Plato',    350,  '2022-03-19');
-INSERT INTO sales_range VALUES (13, 'Gandi',    377,  '2022-01-09');
-
-ALTER TABLE sales_range SPLIT PARTITION sales_all INTO
-  (PARTITION sales_apr2022 FOR VALUES FROM ('2022-04-01') TO ('2022-05-01'),
-   PARTITION sales_feb2022 FOR VALUES FROM ('2022-02-01') TO ('2022-03-01'),
-   PARTITION sales_others DEFAULT);
-
-INSERT INTO sales_range VALUES (14, 'Smith',    510,  '2022-05-04');
-
-SELECT * FROM sales_range;
-SELECT * FROM sales_jan2022;
-SELECT * FROM sales_feb2022;
-SELECT * FROM sales_apr2022;
-SELECT * FROM sales_others;
-
-DROP TABLE sales_range;
-
---
--- Try to SPLIT partition of another table.
---
-CREATE TABLE t1(i int, t text) PARTITION BY LIST (t);
-CREATE TABLE t1pa PARTITION OF t1 FOR VALUES IN ('A');
-CREATE TABLE t2 (i int, t text) PARTITION BY RANGE (t);
-
--- ERROR:  relation "t1pa" is not a partition of relation "t2"
-ALTER TABLE t2 SPLIT PARTITION t1pa INTO
-   (PARTITION t2a FOR VALUES FROM ('A') TO ('B'),
-    PARTITION t2b FOR VALUES FROM ('B') TO ('C'));
-
-DROP TABLE t2;
-DROP TABLE t1;
-
---
--- Try to SPLIT partition of temporary table.
---
-CREATE TEMP TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TEMP TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-
--- Partitions should be temporary.
-SELECT c.oid::pg_catalog.regclass, pg_catalog.pg_get_expr(c.relpartbound, c.oid), c.relpersistence
-  FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i
-  WHERE c.oid = i.inhrelid AND i.inhparent = 't'::regclass
-  ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT', c.oid::pg_catalog.regclass::pg_catalog.text;
-
-DROP TABLE t;
-
--- Check the new partitions inherit parent's tablespace
-CREATE TABLE t (i int PRIMARY KEY USING INDEX TABLESPACE regress_tblspace)
-  PARTITION BY RANGE (i) TABLESPACE regress_tblspace;
-CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-SELECT tablename, tablespace FROM pg_tables
-  WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema'
-  ORDER BY tablename, tablespace;
-SELECT tablename, indexname, tablespace FROM pg_indexes
-  WHERE tablename IN ('t', 'tp_0_1', 'tp_1_2') AND schemaname = 'partition_split_schema'
-  ORDER BY tablename, indexname, tablespace;
-DROP TABLE t;
-
--- Check new partitions inherits parent's table access method
-CREATE ACCESS METHOD partition_split_heap TYPE TABLE HANDLER heap_tableam_handler;
-CREATE TABLE t (i int) PARTITION BY RANGE (i) USING partition_split_heap;
-CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-SELECT c.relname, a.amname
-FROM pg_class c JOIN pg_am a ON c.relam = a.oid
-WHERE c.oid IN ('t'::regclass, 'tp_0_1'::regclass, 'tp_1_2'::regclass)
-ORDER BY c.relname;
-DROP TABLE t;
-DROP ACCESS METHOD partition_split_heap;
-
--- Test permission checks.  The user needs to own the parent table and the
--- the partition to split to do the split.
-CREATE ROLE regress_partition_split_alice;
-CREATE ROLE regress_partition_split_bob;
-GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_alice;
-GRANT ALL ON SCHEMA partition_split_schema TO regress_partition_split_bob;
-
-SET SESSION AUTHORIZATION regress_partition_split_alice;
-CREATE TABLE t (i int) PARTITION BY RANGE (i);
-CREATE TABLE tp_0_2 PARTITION OF t FOR VALUES FROM (0) TO (2);
-
-SET SESSION AUTHORIZATION regress_partition_split_bob;
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-RESET SESSION AUTHORIZATION;
-
-ALTER TABLE t OWNER TO regress_partition_split_bob;
-SET SESSION AUTHORIZATION regress_partition_split_bob;
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-RESET SESSION AUTHORIZATION;
-
-ALTER TABLE tp_0_2 OWNER TO regress_partition_split_bob;
-SET SESSION AUTHORIZATION regress_partition_split_bob;
-ALTER TABLE t SPLIT PARTITION tp_0_2 INTO
-  (PARTITION tp_0_1 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1_2 FOR VALUES FROM (1) TO (2));
-RESET SESSION AUTHORIZATION;
-
-DROP TABLE t;
-REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_alice;
-REVOKE ALL ON SCHEMA partition_split_schema FROM regress_partition_split_bob;
-DROP ROLE regress_partition_split_alice;
-DROP ROLE regress_partition_split_bob;
-
--- Split partition of a temporary table when one of the partitions after
--- split has the same name as the partition being split
-CREATE TEMP TABLE t (a int) PARTITION BY RANGE (a);
-CREATE TEMP TABLE tp_0 PARTITION OF t FOR VALUES FROM (0) TO (2);
-ALTER TABLE t SPLIT PARTITION tp_0 INTO
-  (PARTITION tp_0 FOR VALUES FROM (0) TO (1),
-   PARTITION tp_1 FOR VALUES FROM (1) TO (2));
-DROP TABLE t;
-
-RESET search_path;
-
---
-DROP SCHEMA partition_split_schema;
-DROP SCHEMA partition_split_schema2;
index 3f3a8f2634bab3e6d794e4bb506094906fe6a4ce..9e951a9e6f30a8884c00bc4bd6483d25b4df60f2 100644 (file)
@@ -2659,7 +2659,6 @@ SimpleStats
 SimpleStringList
 SimpleStringListCell
 SingleBoundSortItem
-SinglePartitionSpec
 Size
 SkipPages
 SlabBlock
@@ -2724,7 +2723,6 @@ SpinDelayStatus
 SplitInterval
 SplitLR
 SplitPageLayout
-SplitPartitionContext
 SplitPoint
 SplitTextOutputData
 SplitVar