aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/tablecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r--src/backend/commands/tablecmds.c131
1 files changed, 22 insertions, 109 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 70753e33e43..d69809a2f86 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -68,6 +68,7 @@
#include "parser/parser.h"
#include "rewrite/rewriteDefine.h"
#include "rewrite/rewriteHandler.h"
+#include "rewrite/rewriteManip.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "storage/lock.h"
@@ -253,7 +254,6 @@ static void truncate_check_rel(Relation rel);
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
List **supOids, List **supconstr, int *supOidCount);
static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
-static bool change_varattnos_walker(Node *node, const AttrNumber *newattno);
static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
static void StoreCatalogInheritance(Oid relationId, List *supers);
@@ -1496,7 +1496,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
* parents after the first one, nor if we have dropped columns.)
*/
newattno = (AttrNumber *)
- palloc(tupleDesc->natts * sizeof(AttrNumber));
+ palloc0(tupleDesc->natts * sizeof(AttrNumber));
for (parent_attno = 1; parent_attno <= tupleDesc->natts;
parent_attno++)
@@ -1510,15 +1510,7 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
* Ignore dropped columns in the parent.
*/
if (attribute->attisdropped)
- {
- /*
- * change_varattnos_of_a_node asserts that this is greater
- * than zero, so if anything tries to use it, we should find
- * out.
- */
- newattno[parent_attno - 1] = 0;
- continue;
- }
+ continue; /* leave newattno entry as zero */
/*
* Does it conflict with some previously inherited column?
@@ -1656,14 +1648,30 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
{
char *name = check[i].ccname;
Node *expr;
+ bool found_whole_row;
/* ignore if the constraint is non-inheritable */
if (check[i].ccnoinherit)
continue;
- /* adjust varattnos of ccbin here */
- expr = stringToNode(check[i].ccbin);
- change_varattnos_of_a_node(expr, newattno);
+ /* Adjust Vars to match new table's column numbering */
+ expr = map_variable_attnos(stringToNode(check[i].ccbin),
+ 1, 0,
+ newattno, tupleDesc->natts,
+ &found_whole_row);
+
+ /*
+ * For the moment we have to reject whole-row variables.
+ * We could convert them, if we knew the new table's rowtype
+ * OID, but that hasn't been assigned yet.
+ */
+ if (found_whole_row)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot convert whole-row table reference"),
+ errdetail("Constraint \"%s\" contains a whole-row reference to table \"%s\".",
+ name,
+ RelationGetRelationName(relation))));
/* check for duplicate */
if (!MergeCheckConstraint(constraints, name, expr))
@@ -1867,101 +1875,6 @@ MergeCheckConstraint(List *constraints, char *name, Node *expr)
/*
- * Replace varattno values in an expression tree according to the given
- * map array, that is, varattno N is replaced by newattno[N-1]. It is
- * caller's responsibility to ensure that the array is long enough to
- * define values for all user varattnos present in the tree. System column
- * attnos remain unchanged.
- *
- * Note that the passed node tree is modified in-place!
- */
-void
-change_varattnos_of_a_node(Node *node, const AttrNumber *newattno)
-{
- /* no setup needed, so away we go */
- (void) change_varattnos_walker(node, newattno);
-}
-
-static bool
-change_varattnos_walker(Node *node, const AttrNumber *newattno)
-{
- if (node == NULL)
- return false;
- if (IsA(node, Var))
- {
- Var *var = (Var *) node;
-
- if (var->varlevelsup == 0 && var->varno == 1 &&
- var->varattno > 0)
- {
- /*
- * ??? the following may be a problem when the node is multiply
- * referenced though stringToNode() doesn't create such a node
- * currently.
- */
- Assert(newattno[var->varattno - 1] > 0);
- var->varattno = var->varoattno = newattno[var->varattno - 1];
- }
- return false;
- }
- return expression_tree_walker(node, change_varattnos_walker,
- (void *) newattno);
-}
-
-/*
- * Generate a map for change_varattnos_of_a_node from old and new TupleDesc's,
- * matching according to column name.
- */
-AttrNumber *
-varattnos_map(TupleDesc olddesc, TupleDesc newdesc)
-{
- AttrNumber *attmap;
- int i,
- j;
-
- attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * olddesc->natts);
- for (i = 1; i <= olddesc->natts; i++)
- {
- if (olddesc->attrs[i - 1]->attisdropped)
- continue; /* leave the entry as zero */
-
- for (j = 1; j <= newdesc->natts; j++)
- {
- if (strcmp(NameStr(olddesc->attrs[i - 1]->attname),
- NameStr(newdesc->attrs[j - 1]->attname)) == 0)
- {
- attmap[i - 1] = j;
- break;
- }
- }
- }
- return attmap;
-}
-
-/*
- * Generate a map for change_varattnos_of_a_node from a TupleDesc and a list
- * of ColumnDefs
- */
-AttrNumber *
-varattnos_map_schema(TupleDesc old, List *schema)
-{
- AttrNumber *attmap;
- int i;
-
- attmap = (AttrNumber *) palloc0(sizeof(AttrNumber) * old->natts);
- for (i = 1; i <= old->natts; i++)
- {
- if (old->attrs[i - 1]->attisdropped)
- continue; /* leave the entry as zero */
-
- attmap[i - 1] = findAttrByName(NameStr(old->attrs[i - 1]->attname),
- schema);
- }
- return attmap;
-}
-
-
-/*
* StoreCatalogInheritance
* Updates the system catalogs with proper inheritance information.
*