]> granicus.if.org Git - postgresql/commitdiff
Remove unnecessairly duplicated gram.y productions
authorStephen Frost <sfrost@snowman.net>
Fri, 28 Apr 2017 00:14:39 +0000 (20:14 -0400)
committerStephen Frost <sfrost@snowman.net>
Fri, 28 Apr 2017 00:14:39 +0000 (20:14 -0400)
Declarative partitioning duplicated the TypedTableElement productions,
evidently to remove the need to specify WITH OPTIONS when creating
partitions.  Instead, simply make WITH OPTIONS optional in the
TypedTableElement production and remove all of the duplicate
PartitionElement-related productions.  This change simplifies the
syntax and makes WITH OPTIONS optional when adding defaults, constraints
or storage parameters to columns when creating either typed tables or
partitions.

Also update pg_dump to no longer include WITH OPTIONS, since it's not
necessary, and update the documentation to reflect that WITH OPTIONS is
now optional.

doc/src/sgml/ref/create_foreign_table.sgml
doc/src/sgml/ref/create_table.sgml
src/backend/parser/gram.y
src/bin/pg_dump/pg_dump.c
src/test/regress/expected/create_table.out
src/test/regress/expected/sanity_check.out
src/test/regress/expected/typed_table.out
src/test/regress/sql/create_table.sql
src/test/regress/sql/typed_table.sql

index 5d0dcf567b5d12dabb823aadb53b0da54d0fe9bc..065c982082d3f818780ed0d16c369ceb7700d205 100644 (file)
@@ -29,7 +29,7 @@ CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name
 
 CREATE FOREIGN TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
   PARTITION OF <replaceable class="PARAMETER">parent_table</replaceable> [ (
-  { <replaceable class="PARAMETER">column_name</replaceable> WITH OPTIONS [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
+  { <replaceable class="PARAMETER">column_name</replaceable> [ WITH OPTIONS ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
     | <replaceable>table_constraint</replaceable> }
     [, ... ]
 ) ] <replaceable class="PARAMETER">partition_bound_spec</replaceable>
index a3dc744efa5ec7765d3dde8deac4f458df26ff3c..484f81898b3cefc127fdf91e14dab8e38826f762 100644 (file)
@@ -35,7 +35,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
 
 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
     OF <replaceable class="PARAMETER">type_name</replaceable> [ (
-  { <replaceable class="PARAMETER">column_name</replaceable> WITH OPTIONS [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
+  { <replaceable class="PARAMETER">column_name</replaceable> [ WITH OPTIONS ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
     | <replaceable>table_constraint</replaceable> }
     [, ... ]
 ) ]
@@ -46,7 +46,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
 
 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable class="PARAMETER">table_name</replaceable>
     PARTITION OF <replaceable class="PARAMETER">parent_table</replaceable> [ (
-  { <replaceable class="PARAMETER">column_name</replaceable> [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
+  { <replaceable class="PARAMETER">column_name</replaceable> [ WITH OPTIONS ] [ <replaceable class="PARAMETER">column_constraint</replaceable> [ ... ] ]
     | <replaceable>table_constraint</replaceable> }
     [, ... ]
 ) ] FOR VALUES <replaceable class="PARAMETER">partition_bound_spec</replaceable>
index 89d2836c49ae94a7b1cec3c2c8ba2158f755e280..21cdc7c7da4377f860a465991339de68ffdb1631 100644 (file)
@@ -576,8 +576,6 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <str>                    part_strategy
 %type <partelem>       part_elem
 %type <list>           part_params
-%type <list>           OptPartitionElementList PartitionElementList
-%type <node>           PartitionElement
 %type <node>           ForValues
 %type <node>           partbound_datum
 %type <list>           partbound_datum_list
@@ -3131,7 +3129,7 @@ CreateStmt:       CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
                                        $$ = (Node *)n;
                                }
                | CREATE OptTemp TABLE qualified_name PARTITION OF qualified_name
-                       OptPartitionElementList ForValues OptPartitionSpec OptWith
+                       OptTypedTableElementList ForValues OptPartitionSpec OptWith
                        OnCommitOption OptTableSpace
                                {
                                        CreateStmt *n = makeNode(CreateStmt);
@@ -3150,7 +3148,7 @@ CreateStmt:       CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
                                        $$ = (Node *)n;
                                }
                | CREATE OptTemp TABLE IF_P NOT EXISTS qualified_name PARTITION OF
-                       qualified_name OptPartitionElementList ForValues OptPartitionSpec
+                       qualified_name OptTypedTableElementList ForValues OptPartitionSpec
                        OptWith OnCommitOption OptTableSpace
                                {
                                        CreateStmt *n = makeNode(CreateStmt);
@@ -3213,11 +3211,6 @@ OptTypedTableElementList:
                        | /*EMPTY*/                                                     { $$ = NIL; }
                ;
 
-OptPartitionElementList:
-                       '(' PartitionElementList ')'            { $$ = $2; }
-                       | /*EMPTY*/                                                     { $$ = NIL; }
-               ;
-
 TableElementList:
                        TableElement
                                {
@@ -3240,17 +3233,6 @@ TypedTableElementList:
                                }
                ;
 
-PartitionElementList:
-                       PartitionElement
-                               {
-                                       $$ = list_make1($1);
-                               }
-                       | PartitionElementList ',' PartitionElement
-                               {
-                                       $$ = lappend($1, $3);
-                               }
-               ;
-
 TableElement:
                        columnDef                                                       { $$ = $1; }
                        | TableLikeClause                                       { $$ = $1; }
@@ -3262,28 +3244,6 @@ TypedTableElement:
                        | TableConstraint                                       { $$ = $1; }
                ;
 
-PartitionElement:
-               TableConstraint                                 { $$ = $1; }
-               |       ColId ColQualList
-                       {
-                               ColumnDef *n = makeNode(ColumnDef);
-                               n->colname = $1;
-                               n->typeName = NULL;
-                               n->inhcount = 0;
-                               n->is_local = true;
-                               n->is_not_null = false;
-                               n->is_from_type = false;
-                               n->storage = 0;
-                               n->raw_default = NULL;
-                               n->cooked_default = NULL;
-                               n->collOid = InvalidOid;
-                               SplitColQualList($2, &n->constraints, &n->collClause,
-                                                                yyscanner);
-                               n->location = @1;
-                               $$ = (Node *) n;
-                       }
-               ;
-
 columnDef:     ColId Typename create_generic_options ColQualList
                                {
                                        ColumnDef *n = makeNode(ColumnDef);
@@ -3305,7 +3265,25 @@ columnDef:       ColId Typename create_generic_options ColQualList
                                }
                ;
 
-columnOptions: ColId WITH OPTIONS ColQualList
+columnOptions: ColId ColQualList
+                               {
+                                       ColumnDef *n = makeNode(ColumnDef);
+                                       n->colname = $1;
+                                       n->typeName = NULL;
+                                       n->inhcount = 0;
+                                       n->is_local = true;
+                                       n->is_not_null = false;
+                                       n->is_from_type = false;
+                                       n->storage = 0;
+                                       n->raw_default = NULL;
+                                       n->cooked_default = NULL;
+                                       n->collOid = InvalidOid;
+                                       SplitColQualList($2, &n->constraints, &n->collClause,
+                                                                        yyscanner);
+                                       n->location = @1;
+                                       $$ = (Node *)n;
+                               }
+                               | ColId WITH OPTIONS ColQualList
                                {
                                        ColumnDef *n = makeNode(ColumnDef);
                                        n->colname = $1;
@@ -4872,7 +4850,7 @@ CreateForeignTableStmt:
                                        $$ = (Node *) n;
                                }
                | CREATE FOREIGN TABLE qualified_name
-                       PARTITION OF qualified_name OptPartitionElementList ForValues
+                       PARTITION OF qualified_name OptTypedTableElementList ForValues
                        SERVER name create_generic_options
                                {
                                        CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
@@ -4893,7 +4871,7 @@ CreateForeignTableStmt:
                                        $$ = (Node *) n;
                                }
                | CREATE FOREIGN TABLE IF_P NOT EXISTS qualified_name
-                       PARTITION OF qualified_name OptPartitionElementList ForValues
+                       PARTITION OF qualified_name OptTypedTableElementList ForValues
                        SERVER name create_generic_options
                                {
                                        CreateForeignTableStmt *n = makeNode(CreateForeignTableStmt);
index e9b5c8a448385c1f155ef3a9a309d0e12b70df63..2fda350faa257b404d296f2e401c146697247cb0 100644 (file)
@@ -15267,13 +15267,16 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
                                                continue;
                                        }
 
-                                       /* Attribute type */
-                                       if ((tbinfo->reloftype || tbinfo->partitionOf) &&
-                                               !dopt->binary_upgrade)
-                                       {
-                                               appendPQExpBufferStr(q, " WITH OPTIONS");
-                                       }
-                                       else
+                                       /*
+                                        * Attribute type
+                                        *
+                                        * In binary-upgrade mode, we always include the type.
+                                        * If we aren't in binary-upgrade mode, then we skip the
+                                        * type when creating a typed table ('OF type_name') or a
+                                        * partition ('PARTITION OF'), since the type comes from
+                                        * the parent/partitioned table.
+                                        */
+                                       if (dopt->binary_upgrade || (!tbinfo->reloftype && !tbinfo->partitionOf))
                                        {
                                                appendPQExpBuffer(q, " %s",
                                                                                  tbinfo->atttypnames[j]);
index b6c75d2e81fb67f8cc4b4d0f424c827ec20e0594..3f94250df28ae22c8d91320184758d781c1c6916 100644 (file)
@@ -624,7 +624,7 @@ SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::reg
 -- specify PARTITION BY for a partition
 CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c);
 ERROR:  column "c" named in partition key does not exist
-CREATE TABLE part_c PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE ((b));
+CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b));
 -- create a level-2 partition
 CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
 -- Partition bound in describe output
index 753ad81e43f5904a5497d6c65a800e20af8a22e5..6750152e0f4908bcddc8bbe7cbc997ed77606722 100644 (file)
@@ -93,6 +93,9 @@ onek|t
 onek2|t
 path_tbl|f
 person|f
+persons|f
+persons2|t
+persons3|t
 pg_aggregate|t
 pg_am|t
 pg_amop|t
index 141d3bcf87cc5b790cd18790f9285855801e00e8..5cdd019244e2758441f507074cfbeaf9a1fcaea9 100644 (file)
@@ -1,3 +1,7 @@
+-- Clean up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+DROP TYPE IF EXISTS person_type CASCADE;
+RESET client_min_messages;
 CREATE TABLE ttable1 OF nothing;
 ERROR:  type "nothing" does not exist
 CREATE TYPE person_type AS (id int, name text);
@@ -102,7 +106,32 @@ SELECT id, namelen(persons) FROM persons;
   1 |       4
 (1 row)
 
-DROP TYPE person_type CASCADE;
-NOTICE:  drop cascades to 2 other objects
-DETAIL:  drop cascades to table persons
-drop cascades to function namelen(person_type)
+CREATE TABLE persons2 OF person_type (
+    id WITH OPTIONS PRIMARY KEY,
+    UNIQUE (name)
+);
+\d persons2
+              Table "public.persons2"
+ Column |  Type   | Collation | Nullable | Default 
+--------+---------+-----------+----------+---------
+ id     | integer |           | not null | 
+ name   | text    |           |          | 
+Indexes:
+    "persons2_pkey" PRIMARY KEY, btree (id)
+    "persons2_name_key" UNIQUE CONSTRAINT, btree (name)
+Typed table of type: person_type
+
+CREATE TABLE persons3 OF person_type (
+    PRIMARY KEY (id),
+    name NOT NULL DEFAULT ''
+);
+\d persons3
+              Table "public.persons3"
+ Column |  Type   | Collation | Nullable | Default  
+--------+---------+-----------+----------+----------
+ id     | integer |           | not null | 
+ name   | text    |           | not null | ''::text
+Indexes:
+    "persons3_pkey" PRIMARY KEY, btree (id)
+Typed table of type: person_type
+
index b00d9e87b823a8f5c2ffa1a69b749a7274fb5952..f08942f7d213906be3c9e344905fe5e30f0200d8 100644 (file)
@@ -578,7 +578,7 @@ SELECT conislocal, coninhcount FROM pg_constraint WHERE conrelid = 'part_b'::reg
 
 -- specify PARTITION BY for a partition
 CREATE TABLE fail_part_col_not_found PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE (c);
-CREATE TABLE part_c PARTITION OF parted FOR VALUES IN ('c') PARTITION BY RANGE ((b));
+CREATE TABLE part_c PARTITION OF parted (b WITH OPTIONS NOT NULL DEFAULT 0) FOR VALUES IN ('c') PARTITION BY RANGE ((b));
 
 -- create a level-2 partition
 CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
index 25aaccb8bcdf219d32b68dbf41e8e648148808ca..1cdceef3637e8a648ab69f9629a54ee548fec6de 100644 (file)
@@ -1,3 +1,10 @@
+-- Clean up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+
+DROP TYPE IF EXISTS person_type CASCADE;
+
+RESET client_min_messages;
+
 CREATE TABLE ttable1 OF nothing;
 
 CREATE TYPE person_type AS (id int, name text);
@@ -60,4 +67,16 @@ INSERT INTO persons VALUES (1, 'test');
 CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$;
 SELECT id, namelen(persons) FROM persons;
 
-DROP TYPE person_type CASCADE;
+CREATE TABLE persons2 OF person_type (
+    id WITH OPTIONS PRIMARY KEY,
+    UNIQUE (name)
+);
+
+\d persons2
+
+CREATE TABLE persons3 OF person_type (
+    PRIMARY KEY (id),
+    name NOT NULL DEFAULT ''
+);
+
+\d persons3