Commit b9a3ef55 authored by Stephen Frost's avatar Stephen Frost

Remove unnecessairly duplicated gram.y productions

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.
parent ab9c4338
......@@ -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>
......
......@@ -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>
......
......@@ -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);
......
......@@ -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]);
......
......@@ -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
......
......@@ -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
......
-- 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
......@@ -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);
......
-- 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment