aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/sequence.c1
-rw-r--r--src/backend/commands/tablecmds.c99
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/nodes/makefuncs.c1
-rw-r--r--src/backend/nodes/outfuncs.c1
-rw-r--r--src/backend/parser/gram.y4
-rw-r--r--src/backend/parser/parse_utilcmd.c2
8 files changed, 46 insertions, 64 deletions
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 89122d4ad75..6d89925b237 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -172,7 +172,6 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
coldef->is_local = true;
coldef->is_not_null = true;
coldef->is_from_type = false;
- coldef->is_from_parent = false;
coldef->storage = 0;
coldef->raw_default = NULL;
coldef->cooked_default = NULL;
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 6048334c755..a0279ae3838 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -1893,17 +1893,6 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
MaxHeapAttributeNumber)));
/*
- * In case of a partition, there are no new column definitions, only dummy
- * ColumnDefs created for column constraints. We merge them with the
- * constraints inherited from the parent.
- */
- if (is_partition)
- {
- saved_schema = schema;
- schema = NIL;
- }
-
- /*
* Check for duplicate names in the explicit list of attributes.
*
* Although we might consider merging such entries in the same way that we
@@ -1916,17 +1905,19 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
ListCell *rest = lnext(entry);
ListCell *prev = entry;
- if (coldef->typeName == NULL)
-
+ if (!is_partition && coldef->typeName == NULL)
+ {
/*
* Typed table column option that does not belong to a column from
* the type. This works because the columns from the type come
- * first in the list.
+ * first in the list. (We omit this check for partition column
+ * lists; those are processed separately below.)
*/
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" does not exist",
coldef->colname)));
+ }
while (rest != NULL)
{
@@ -1960,6 +1951,17 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
}
/*
+ * In case of a partition, there are no new column definitions, only dummy
+ * ColumnDefs created for column constraints. Set them aside for now and
+ * process them at the end.
+ */
+ if (is_partition)
+ {
+ saved_schema = schema;
+ schema = NIL;
+ }
+
+ /*
* Scan the parents left-to-right, and merge their attributes to form a
* list of inherited attributes (inhSchema). Also check to see if we need
* to inherit an OID column.
@@ -2175,7 +2177,6 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
def->is_local = false;
def->is_not_null = attribute->attnotnull;
def->is_from_type = false;
- def->is_from_parent = true;
def->storage = attribute->attstorage;
def->raw_default = NULL;
def->cooked_default = NULL;
@@ -2428,59 +2429,51 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
/*
* Now that we have the column definition list for a partition, we can
* check whether the columns referenced in the column constraint specs
- * actually exist. Also, we merge the constraints into the corresponding
- * column definitions.
+ * actually exist. Also, we merge NOT NULL and defaults into each
+ * corresponding column definition.
*/
- if (is_partition && list_length(saved_schema) > 0)
+ if (is_partition)
{
- schema = list_concat(schema, saved_schema);
-
- foreach(entry, schema)
+ foreach(entry, saved_schema)
{
- ColumnDef *coldef = lfirst(entry);
- ListCell *rest = lnext(entry);
- ListCell *prev = entry;
+ ColumnDef *restdef = lfirst(entry);
+ bool found = false;
+ ListCell *l;
- /*
- * Partition column option that does not belong to a column from
- * the parent. This works because the columns from the parent
- * come first in the list (see above).
- */
- if (coldef->typeName == NULL)
- ereport(ERROR,
- (errcode(ERRCODE_UNDEFINED_COLUMN),
- errmsg("column \"%s\" does not exist",
- coldef->colname)));
- while (rest != NULL)
+ foreach(l, schema)
{
- ColumnDef *restdef = lfirst(rest);
- ListCell *next = lnext(rest); /* need to save it in case we
- * delete it */
+ ColumnDef *coldef = lfirst(l);
if (strcmp(coldef->colname, restdef->colname) == 0)
{
+ found = true;
+ coldef->is_not_null |= restdef->is_not_null;
+
/*
- * merge the column options into the column from the
- * parent
+ * Override the parent's default value for this column
+ * (coldef->cooked_default) with the partition's local
+ * definition (restdef->raw_default), if there's one. It
+ * should be physically impossible to get a cooked default
+ * in the local definition or a raw default in the
+ * inherited definition, but make sure they're nulls, for
+ * future-proofing.
*/
- if (coldef->is_from_parent)
+ Assert(restdef->cooked_default == NULL);
+ Assert(coldef->raw_default == NULL);
+ if (restdef->raw_default)
{
- coldef->is_not_null = restdef->is_not_null;
coldef->raw_default = restdef->raw_default;
- coldef->cooked_default = restdef->cooked_default;
- coldef->constraints = restdef->constraints;
- coldef->is_from_parent = false;
- list_delete_cell(schema, rest, prev);
+ coldef->cooked_default = NULL;
}
- else
- ereport(ERROR,
- (errcode(ERRCODE_DUPLICATE_COLUMN),
- errmsg("column \"%s\" specified more than once",
- coldef->colname)));
}
- prev = rest;
- rest = next;
}
+
+ /* complain for constraints on columns not in parent */
+ if (!found)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_COLUMN),
+ errmsg("column \"%s\" does not exist",
+ restdef->colname)));
}
}
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index e8ea59e34af..db499684096 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -2873,7 +2873,6 @@ _copyColumnDef(const ColumnDef *from)
COPY_SCALAR_FIELD(is_local);
COPY_SCALAR_FIELD(is_not_null);
COPY_SCALAR_FIELD(is_from_type);
- COPY_SCALAR_FIELD(is_from_parent);
COPY_SCALAR_FIELD(storage);
COPY_NODE_FIELD(raw_default);
COPY_NODE_FIELD(cooked_default);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 3bb91c95958..3a084b4d1f1 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2553,7 +2553,6 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b)
COMPARE_SCALAR_FIELD(is_local);
COMPARE_SCALAR_FIELD(is_not_null);
COMPARE_SCALAR_FIELD(is_from_type);
- COMPARE_SCALAR_FIELD(is_from_parent);
COMPARE_SCALAR_FIELD(storage);
COMPARE_NODE_FIELD(raw_default);
COMPARE_NODE_FIELD(cooked_default);
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 1bd2599c2c5..4a2e669a864 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -496,7 +496,6 @@ makeColumnDef(const char *colname, Oid typeOid, int32 typmod, Oid collOid)
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
- n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 69731ccdea2..f0c396530df 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -2874,7 +2874,6 @@ _outColumnDef(StringInfo str, const ColumnDef *node)
WRITE_BOOL_FIELD(is_local);
WRITE_BOOL_FIELD(is_not_null);
WRITE_BOOL_FIELD(is_from_type);
- WRITE_BOOL_FIELD(is_from_parent);
WRITE_CHAR_FIELD(storage);
WRITE_NODE_FIELD(raw_default);
WRITE_NODE_FIELD(cooked_default);
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 6d23bfb0b35..2effd511358 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -3388,7 +3388,6 @@ columnDef: ColId Typename create_generic_options ColQualList
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
- n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
@@ -3410,7 +3409,6 @@ columnOptions: ColId ColQualList
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
- n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
@@ -3429,7 +3427,6 @@ columnOptions: ColId ColQualList
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
- n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
@@ -12267,7 +12264,6 @@ TableFuncElement: ColId Typename opt_collate_clause
n->is_local = true;
n->is_not_null = false;
n->is_from_type = false;
- n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index a6a2de94ea4..2e222d822b3 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -988,7 +988,6 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
def->is_local = true;
def->is_not_null = attribute->attnotnull;
def->is_from_type = false;
- def->is_from_parent = false;
def->storage = 0;
def->raw_default = NULL;
def->cooked_default = NULL;
@@ -1265,7 +1264,6 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
n->is_local = true;
n->is_not_null = false;
n->is_from_type = true;
- n->is_from_parent = false;
n->storage = 0;
n->raw_default = NULL;
n->cooked_default = NULL;