]> granicus.if.org Git - postgresql/commitdiff
Clean up generation of default names for constraints, indexes, and serial
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 10 Jun 2004 17:56:03 +0000 (17:56 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 10 Jun 2004 17:56:03 +0000 (17:56 +0000)
sequences, as per recent discussion.  All these names are now of the
form table_column_type, with digits added if needed to make them unique.
Default constraint names are chosen to be unique across their whole schema,
not just within the parent object, so as to be more SQL-spec-compatible
and make the information schema views more useful.

20 files changed:
src/backend/catalog/heap.c
src/backend/catalog/pg_constraint.c
src/backend/commands/indexcmds.c
src/backend/commands/tablecmds.c
src/backend/commands/typecmds.c
src/backend/parser/analyze.c
src/include/catalog/pg_constraint.h
src/include/commands/defrem.h
src/include/parser/analyze.h
src/test/regress/expected/alter_table.out
src/test/regress/expected/cluster.out
src/test/regress/expected/copy2.out
src/test/regress/expected/domain.out
src/test/regress/expected/foreign_key.out
src/test/regress/expected/namespace.out
src/test/regress/expected/rules.out
src/test/regress/expected/sequence.out
src/test/regress/expected/truncate.out
src/test/regress/output/constraints.source
src/test/regress/sql/copy2.sql

index 718c3b9091035dcadef404db96f47d7d1f3cab34..a4cc33d4c9d2c041e142931e5feb5589d801768e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.269 2004/06/06 20:30:07 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/heap.c,v 1.270 2004/06/10 17:55:53 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1488,7 +1488,7 @@ AddRelationRawConstraints(Relation rel,
        ParseState *pstate;
        RangeTblEntry *rte;
        int                     numchecks;
-       int                     constr_name_ctr = 0;
+       List       *checknames;
        ListCell   *cell;
        Node       *expr;
        CookedConstraint *cooked;
@@ -1547,6 +1547,7 @@ AddRelationRawConstraints(Relation rel,
         * Process constraint expressions.
         */
        numchecks = numoldchecks;
+       checknames = NIL;
        foreach(cell, rawConstraints)
        {
                Constraint *cdef = (Constraint *) lfirst(cell);
@@ -1556,81 +1557,6 @@ AddRelationRawConstraints(Relation rel,
                        continue;
                Assert(cdef->cooked_expr == NULL);
 
-               /* Check name uniqueness, or generate a new name */
-               if (cdef->name != NULL)
-               {
-                       ListCell   *cell2;
-
-                       ccname = cdef->name;
-                       /* Check against pre-existing constraints */
-                       if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
-                                                                        RelationGetRelid(rel),
-                                                                        RelationGetNamespace(rel),
-                                                                        ccname))
-                               ereport(ERROR,
-                                               (errcode(ERRCODE_DUPLICATE_OBJECT),
-                                                errmsg("constraint \"%s\" for relation \"%s\" already exists",
-                                                               ccname, RelationGetRelationName(rel))));
-                       /* Check against other new constraints */
-                       /* Needed because we don't do CommandCounterIncrement in loop */
-                       foreach(cell2, rawConstraints)
-                       {
-                               Constraint *cdef2 = (Constraint *) lfirst(cell2);
-
-                               if (cdef2 == cdef ||
-                                       cdef2->contype != CONSTR_CHECK ||
-                                       cdef2->raw_expr == NULL ||
-                                       cdef2->name == NULL)
-                                       continue;
-                               if (strcmp(cdef2->name, ccname) == 0)
-                                       ereport(ERROR,
-                                                       (errcode(ERRCODE_DUPLICATE_OBJECT),
-                                                errmsg("check constraint \"%s\" already exists",
-                                                               ccname)));
-                       }
-               }
-               else
-               {
-                       bool            success;
-
-                       do
-                       {
-                               ListCell   *cell2;
-
-                               /*
-                                * Generate a name that does not conflict with
-                                * pre-existing constraints, nor with any auto-generated
-                                * names so far.
-                                */
-                               ccname = GenerateConstraintName(CONSTRAINT_RELATION,
-                                                                                               RelationGetRelid(rel),
-                                                                                               RelationGetNamespace(rel),
-                                                                                               &constr_name_ctr);
-
-                               /*
-                                * Check against other new constraints, in case the user
-                                * has specified a name that looks like an auto-generated
-                                * name.
-                                */
-                               success = true;
-                               foreach(cell2, rawConstraints)
-                               {
-                                       Constraint *cdef2 = (Constraint *) lfirst(cell2);
-
-                                       if (cdef2 == cdef ||
-                                               cdef2->contype != CONSTR_CHECK ||
-                                               cdef2->raw_expr == NULL ||
-                                               cdef2->name == NULL)
-                                               continue;
-                                       if (strcmp(cdef2->name, ccname) == 0)
-                                       {
-                                               success = false;
-                                               break;
-                                       }
-                               }
-                       } while (!success);
-               }
-
                /*
                 * Transform raw parsetree to executable expression.
                 */
@@ -1662,6 +1588,73 @@ AddRelationRawConstraints(Relation rel,
                                        (errcode(ERRCODE_GROUPING_ERROR),
                                         errmsg("cannot use aggregate function in check constraint")));
 
+               /*
+                * Check name uniqueness, or generate a name if none was given.
+                */
+               if (cdef->name != NULL)
+               {
+                       ListCell   *cell2;
+
+                       ccname = cdef->name;
+                       /* Check against pre-existing constraints */
+                       if (ConstraintNameIsUsed(CONSTRAINT_RELATION,
+                                                                        RelationGetRelid(rel),
+                                                                        RelationGetNamespace(rel),
+                                                                        ccname))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_DUPLICATE_OBJECT),
+                                                errmsg("constraint \"%s\" for relation \"%s\" already exists",
+                                                               ccname, RelationGetRelationName(rel))));
+                       /* Check against other new constraints */
+                       /* Needed because we don't do CommandCounterIncrement in loop */
+                       foreach(cell2, checknames)
+                       {
+                               if (strcmp((char *) lfirst(cell2), ccname) == 0)
+                                       ereport(ERROR,
+                                                       (errcode(ERRCODE_DUPLICATE_OBJECT),
+                                                        errmsg("check constraint \"%s\" already exists",
+                                                                       ccname)));
+                       }
+               }
+               else
+               {
+                       /*
+                        * When generating a name, we want to create "tab_col_check"
+                        * for a column constraint and "tab_check" for a table
+                        * constraint.  We no longer have any info about the
+                        * syntactic positioning of the constraint phrase, so we
+                        * approximate this by seeing whether the expression references
+                        * more than one column.  (If the user played by the rules,
+                        * the result is the same...)
+                        *
+                        * Note: pull_var_clause() doesn't descend into sublinks,
+                        * but we eliminated those above; and anyway this only needs
+                        * to be an approximate answer.
+                        */
+                       List *vars;
+                       char *colname;
+
+                       vars = pull_var_clause(expr, false);
+
+                       /* eliminate duplicates */
+                       vars = list_union(NIL, vars);
+
+                       if (list_length(vars) == 1)
+                               colname = get_attname(RelationGetRelid(rel),
+                                                                         ((Var *) linitial(vars))->varattno);
+                       else
+                               colname = NULL;
+
+                       ccname = ChooseConstraintName(RelationGetRelationName(rel),
+                                                                                 colname,
+                                                                                 "check",
+                                                                                 RelationGetNamespace(rel),
+                                                                                 checknames);
+               }
+
+               /* save name for future checks */
+               checknames = lappend(checknames, ccname);
+
                /*
                 * OK, store it.
                 */
index 09f3acd5f39fe54f06342b791c892dfda472fe79..4bd9409b8de87c44d1d6e2ddeb2a9155bc019b43 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.19 2003/11/29 19:51:46 pgsql Exp $
+ *       $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.20 2004/06/10 17:55:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,6 +22,7 @@
 #include "catalog/indexing.h"
 #include "catalog/pg_constraint.h"
 #include "catalog/pg_type.h"
+#include "commands/defrem.h"
 #include "miscadmin.h"
 #include "utils/array.h"
 #include "utils/builtins.h"
@@ -263,13 +264,19 @@ CreateConstraintEntry(const char *constraintName,
 
 /*
  * Test whether given name is currently used as a constraint name
- * for the given relation.
+ * for the given object (relation or domain).
  *
- * NB: Caller should hold exclusive lock on the given relation, else
- * this test is not very meaningful.
+ * This is used to decide whether to accept a user-specified constraint name.
+ * It is deliberately not the same test as ChooseConstraintName uses to decide
+ * whether an auto-generated name is OK: here, we will allow it unless there
+ * is an identical constraint name in use *on the same object*.
+ *
+ * NB: Caller should hold exclusive lock on the given object, else
+ * this test can be fooled by concurrent additions.
  */
 bool
-ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, const char *cname)
+ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId,
+                                        Oid objNamespace, const char *conname)
 {
        bool            found;
        Relation        conDesc;
@@ -277,14 +284,14 @@ ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, con
        ScanKeyData skey[2];
        HeapTuple       tup;
 
-       conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
+       conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
 
        found = false;
 
        ScanKeyInit(&skey[0],
                                Anum_pg_constraint_conname,
                                BTEqualStrategyNumber, F_NAMEEQ,
-                               CStringGetDatum(cname));
+                               CStringGetDatum(conname));
 
        ScanKeyInit(&skey[1],
                                Anum_pg_constraint_connamespace,
@@ -311,101 +318,99 @@ ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, con
        }
 
        systable_endscan(conscan);
-       heap_close(conDesc, RowExclusiveLock);
+       heap_close(conDesc, AccessShareLock);
 
        return found;
 }
 
 /*
- * Generate a currently-unused constraint name for the given relation.
+ * Select a nonconflicting name for a new constraint.
+ *
+ * The objective here is to choose a name that is unique within the
+ * specified namespace.  Postgres does not require this, but the SQL
+ * spec does, and some apps depend on it.  Therefore we avoid choosing
+ * default names that so conflict.
+ *
+ * name1, name2, and label are used the same way as for makeObjectName(),
+ * except that the label can't be NULL; digits will be appended to the label
+ * if needed to create a name that is unique within the specified namespace.
  *
- * The passed counter should be initialized to 0 the first time through.
- * If multiple constraint names are to be generated in a single command,
- * pass the new counter value to each successive call, else the same
- * name will be generated each time.
+ * 'others' can be a list of string names already chosen within the current
+ * command (but not yet reflected into the catalogs); we will not choose
+ * a duplicate of one of these either.
  *
- * NB: Caller should hold exclusive lock on the given relation, else
- * someone else might choose the same name concurrently!
+ * Note: it is theoretically possible to get a collision anyway, if someone
+ * else chooses the same name concurrently.  This is fairly unlikely to be
+ * a problem in practice, especially if one is holding an exclusive lock on
+ * the relation identified by name1.
+ *
+ * Returns a palloc'd string.
  */
 char *
-GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, int *counter)
+ChooseConstraintName(const char *name1, const char *name2,
+                                        const char *label, Oid namespace,
+                                        List *others)
 {
-       bool            found;
+       int                     pass = 0;
+       char       *conname = NULL;
+       char            modlabel[NAMEDATALEN];
        Relation        conDesc;
-       char       *cname;
+       SysScanDesc conscan;
+       ScanKeyData skey[2];
+       bool            found;
+       ListCell   *l;
 
-       cname = (char *) palloc(NAMEDATALEN * sizeof(char));
+       conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
 
-       conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
+       /* try the unmodified label first */
+       StrNCpy(modlabel, label, sizeof(modlabel));
 
-       /* Loop until we find a non-conflicting constraint name */
-       /* We assume there will be one eventually ... */
-       do
+       for (;;)
        {
-               SysScanDesc conscan;
-               ScanKeyData skey[2];
-               HeapTuple       tup;
-
-               ++(*counter);
-               snprintf(cname, NAMEDATALEN, "$%d", *counter);
+               conname = makeObjectName(name1, name2, modlabel);
 
-               /*
-                * This duplicates ConstraintNameIsUsed() so that we can avoid
-                * re-opening pg_constraint for each iteration.
-                */
                found = false;
 
-               ScanKeyInit(&skey[0],
-                                       Anum_pg_constraint_conname,
-                                       BTEqualStrategyNumber, F_NAMEEQ,
-                                       CStringGetDatum(cname));
-
-               ScanKeyInit(&skey[1],
-                                       Anum_pg_constraint_connamespace,
-                                       BTEqualStrategyNumber, F_OIDEQ,
-                                       ObjectIdGetDatum(objNamespace));
-
-               conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
-                                                                        SnapshotNow, 2, skey);
-
-               while (HeapTupleIsValid(tup = systable_getnext(conscan)))
+               foreach(l, others)
                {
-                       Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
-
-                       if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)
-                       {
-                               found = true;
-                               break;
-                       }
-                       else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)
+                       if (strcmp((char *) lfirst(l), conname) == 0)
                        {
                                found = true;
                                break;
                        }
                }
 
-               systable_endscan(conscan);
-       } while (found);
+               if (!found)
+               {
+                       ScanKeyInit(&skey[0],
+                                               Anum_pg_constraint_conname,
+                                               BTEqualStrategyNumber, F_NAMEEQ,
+                                               CStringGetDatum(conname));
 
-       heap_close(conDesc, RowExclusiveLock);
+                       ScanKeyInit(&skey[1],
+                                               Anum_pg_constraint_connamespace,
+                                               BTEqualStrategyNumber, F_OIDEQ,
+                                               ObjectIdGetDatum(namespace));
 
-       return cname;
-}
+                       conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
+                                                                                SnapshotNow, 2, skey);
 
-/*
- * Does the given name look like a generated constraint name?
- *
- * This is a test on the form of the name, *not* on whether it has
- * actually been assigned.
- */
-bool
-ConstraintNameIsGenerated(const char *cname)
-{
-       if (cname[0] != '$')
-               return false;
-       if (strspn(cname + 1, "0123456789") != strlen(cname + 1))
-               return false;
-       return true;
+                       found = (HeapTupleIsValid(systable_getnext(conscan)));
+
+                       systable_endscan(conscan);
+               }
+
+               if (!found)
+                       break;
+
+               /* found a conflict, so try a new name component */
+               pfree(conname);
+               snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
+       }
+
+       heap_close(conDesc, AccessShareLock);
+
+       return conname;
 }
 
 /*
index 1fe8e58e585525e85b2e897fd66d6c776d28923e..d141c83c1bf517fc72b44ac9488e9335df41fed4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.120 2004/05/26 04:41:11 neilc Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/indexcmds.c,v 1.121 2004/06/10 17:55:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "commands/defrem.h"
 #include "commands/tablecmds.h"
 #include "executor/executor.h"
+#include "mb/pg_wchar.h"
 #include "miscadmin.h"
 #include "optimizer/clauses.h"
 #include "optimizer/prep.h"
-#include "parser/analyze.h"
 #include "parser/parsetree.h"
 #include "parser/parse_coerce.h"
 #include "parser/parse_expr.h"
@@ -53,8 +53,6 @@ static void ComputeIndexAttrs(IndexInfo *indexInfo, Oid *classOidP,
 static Oid GetIndexOpClass(List *opclass, Oid attrType,
                                char *accessMethodName, Oid accessMethodId);
 static Oid     GetDefaultOpClass(Oid attrType, Oid accessMethodId);
-static char *CreateIndexName(const char *table_name, const char *column_name,
-                                                        const char *label, Oid inamespace);
 static bool relationHasPrimaryKey(Relation rel);
 
 
@@ -159,18 +157,18 @@ DefineIndex(RangeVar *heapRelation,
        if (indexRelationName == NULL)
        {
                if (primary)
-                       indexRelationName = CreateIndexName(RelationGetRelationName(rel),
-                                                                                               NULL,
-                                                                                               "pkey",
-                                                                                               namespaceId);
+                       indexRelationName = ChooseRelationName(RelationGetRelationName(rel),
+                                                                                                  NULL,
+                                                                                                  "pkey",
+                                                                                                  namespaceId);
                else
                {
                        IndexElem  *iparam = (IndexElem *) linitial(attributeList);
 
-                       indexRelationName = CreateIndexName(RelationGetRelationName(rel),
-                                                                                               iparam->name,
-                                                                                               "key",
-                                                                                               namespaceId);
+                       indexRelationName = ChooseRelationName(RelationGetRelationName(rel),
+                                                                                                  iparam->name,
+                                                                                                  "key",
+                                                                                                  namespaceId);
                }
        }
 
@@ -657,35 +655,131 @@ GetDefaultOpClass(Oid attrType, Oid accessMethodId)
 }
 
 /*
- * Select a nonconflicting name for an index.
+ *     makeObjectName()
+ *
+ *     Create a name for an implicitly created index, sequence, constraint, etc.
+ *
+ *     The parameters are typically: the original table name, the original field
+ *     name, and a "type" string (such as "seq" or "pkey").    The field name
+ *     and/or type can be NULL if not relevant.
+ *
+ *     The result is a palloc'd string.
+ *
+ *     The basic result we want is "name1_name2_label", omitting "_name2" or
+ *     "_label" when those parameters are NULL.  However, we must generate
+ *     a name with less than NAMEDATALEN characters!  So, we truncate one or
+ *     both names if necessary to make a short-enough string.  The label part
+ *     is never truncated (so it had better be reasonably short).
+ *
+ *     The caller is responsible for checking uniqueness of the generated
+ *     name and retrying as needed; retrying will be done by altering the
+ *     "label" string (which is why we never truncate that part).
  */
-static char *
-CreateIndexName(const char *table_name, const char *column_name,
-                               const char *label, Oid inamespace)
+char *
+makeObjectName(const char *name1, const char *name2, const char *label)
 {
-       int                     pass = 0;
-       char       *iname = NULL;
-       char            typename[NAMEDATALEN];
+       char       *name;
+       int                     overhead = 0;   /* chars needed for label and underscores */
+       int                     availchars;             /* chars available for name(s) */
+       int                     name1chars;             /* chars allocated to name1 */
+       int                     name2chars;             /* chars allocated to name2 */
+       int                     ndx;
+
+       name1chars = strlen(name1);
+       if (name2)
+       {
+               name2chars = strlen(name2);
+               overhead++;                             /* allow for separating underscore */
+       }
+       else
+               name2chars = 0;
+       if (label)
+               overhead += strlen(label) + 1;
+
+       availchars = NAMEDATALEN - 1 - overhead;
+       Assert(availchars > 0);         /* else caller chose a bad label */
 
        /*
-        * The type name for makeObjectName is label, or labelN if that's
-        * necessary to prevent collision with existing indexes.
+        * If we must truncate,  preferentially truncate the longer name. This
+        * logic could be expressed without a loop, but it's simple and
+        * obvious as a loop.
         */
-       strncpy(typename, label, sizeof(typename));
+       while (name1chars + name2chars > availchars)
+       {
+               if (name1chars > name2chars)
+                       name1chars--;
+               else
+                       name2chars--;
+       }
+
+       if (name1)
+               name1chars = pg_mbcliplen(name1, name1chars, name1chars);
+       if (name2)
+               name2chars = pg_mbcliplen(name2, name2chars, name2chars);
+
+       /* Now construct the string using the chosen lengths */
+       name = palloc(name1chars + name2chars + overhead + 1);
+       memcpy(name, name1, name1chars);
+       ndx = name1chars;
+       if (name2)
+       {
+               name[ndx++] = '_';
+               memcpy(name + ndx, name2, name2chars);
+               ndx += name2chars;
+       }
+       if (label)
+       {
+               name[ndx++] = '_';
+               strcpy(name + ndx, label);
+       }
+       else
+               name[ndx] = '\0';
+
+       return name;
+}
+
+/*
+ * Select a nonconflicting name for a new relation.  This is ordinarily
+ * used to choose index names (which is why it's here) but it can also
+ * be used for sequences, or any autogenerated relation kind.
+ *
+ * name1, name2, and label are used the same way as for makeObjectName(),
+ * except that the label can't be NULL; digits will be appended to the label
+ * if needed to create a name that is unique within the specified namespace.
+ *
+ * Note: it is theoretically possible to get a collision anyway, if someone
+ * else chooses the same name concurrently.  This is fairly unlikely to be
+ * a problem in practice, especially if one is holding an exclusive lock on
+ * the relation identified by name1.  However, if choosing multiple names
+ * within a single command, you'd better create the new object and do
+ * CommandCounterIncrement before choosing the next one!
+ *
+ * Returns a palloc'd string.
+ */
+char *
+ChooseRelationName(const char *name1, const char *name2,
+                                  const char *label, Oid namespace)
+{
+       int                     pass = 0;
+       char       *relname = NULL;
+       char            modlabel[NAMEDATALEN];
+
+       /* try the unmodified label first */
+       StrNCpy(modlabel, label, sizeof(modlabel));
 
        for (;;)
        {
-               iname = makeObjectName(table_name, column_name, typename);
+               relname = makeObjectName(name1, name2, modlabel);
 
-               if (!OidIsValid(get_relname_relid(iname, inamespace)))
+               if (!OidIsValid(get_relname_relid(relname, namespace)))
                        break;
 
                /* found a conflict, so try a new name component */
-               pfree(iname);
-               snprintf(typename, sizeof(typename), "%s%d", label, ++pass);
+               pfree(relname);
+               snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);
        }
 
-       return iname;
+       return relname;
 }
 
 /*
index 3a95064442c99837b92438801c4c015c19c7b34f..7b0b35840ee5389221fa1f04690ecc20e0942a15 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.112 2004/06/06 20:30:07 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.113 2004/06/10 17:55:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -124,8 +124,6 @@ typedef struct AlteredTableInfo
        List       *changedConstraintDefs;      /* string definitions of same */
        List       *changedIndexOids;   /* OIDs of indexes to rebuild */
        List       *changedIndexDefs;   /* string definitions of same */
-       /* Workspace for ATExecAddConstraint */
-       int                     constr_name_ctr;
 } AlteredTableInfo;
 
 /* Struct describing one new constraint to check in Phase 3 scan */
@@ -323,46 +321,45 @@ DefineRelation(CreateStmt *stmt, char relkind)
 
        if (old_constraints != NIL)
        {
-               ConstrCheck *check = (ConstrCheck *) palloc(list_length(old_constraints) *
-                                                                                                       sizeof(ConstrCheck));
+               ConstrCheck *check = (ConstrCheck *)
+                       palloc0(list_length(old_constraints) * sizeof(ConstrCheck));
                int                     ncheck = 0;
-               int                     constr_name_ctr = 0;
 
                foreach(listptr, old_constraints)
                {
                        Constraint *cdef = (Constraint *) lfirst(listptr);
+                       bool dup = false;
 
                        if (cdef->contype != CONSTR_CHECK)
                                continue;
-
-                       if (cdef->name != NULL)
+                       Assert(cdef->name != NULL);
+                       Assert(cdef->raw_expr == NULL && cdef->cooked_expr != NULL);
+                       /*
+                        * In multiple-inheritance situations, it's possible to inherit
+                        * the same grandparent constraint through multiple parents.
+                        * Hence, discard inherited constraints that match as to both
+                        * name and expression.  Otherwise, gripe if the names conflict.
+                        */
+                       for (i = 0; i < ncheck; i++)
                        {
-                               for (i = 0; i < ncheck; i++)
+                               if (strcmp(check[i].ccname, cdef->name) != 0)
+                                       continue;
+                               if (strcmp(check[i].ccbin, cdef->cooked_expr) == 0)
                                {
-                                       if (strcmp(check[i].ccname, cdef->name) == 0)
-                                               ereport(ERROR,
-                                                               (errcode(ERRCODE_DUPLICATE_OBJECT),
+                                       dup = true;
+                                       break;
+                               }
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_DUPLICATE_OBJECT),
                                                 errmsg("duplicate check constraint name \"%s\"",
                                                                cdef->name)));
-                               }
-                               check[ncheck].ccname = cdef->name;
                        }
-                       else
+                       if (!dup)
                        {
-                               /*
-                                * Generate a constraint name.  NB: this should match the
-                                * form of names that GenerateConstraintName() may produce
-                                * for names added later.  We are assured that there is no
-                                * name conflict, because MergeAttributes() did not pass
-                                * back any names of this form.
-                                */
-                               check[ncheck].ccname = (char *) palloc(NAMEDATALEN);
-                               snprintf(check[ncheck].ccname, NAMEDATALEN, "$%d",
-                                                ++constr_name_ctr);
+                               check[ncheck].ccname = cdef->name;
+                               check[ncheck].ccbin = pstrdup(cdef->cooked_expr);
+                               ncheck++;
                        }
-                       Assert(cdef->raw_expr == NULL && cdef->cooked_expr != NULL);
-                       check[ncheck].ccbin = pstrdup(cdef->cooked_expr);
-                       ncheck++;
                }
                if (ncheck > 0)
                {
@@ -867,17 +864,7 @@ MergeAttributes(List *schema, List *supers, bool istemp,
                                Node       *expr;
 
                                cdef->contype = CONSTR_CHECK;
-
-                               /*
-                                * Do not inherit generated constraint names, since they
-                                * might conflict across multiple inheritance parents.
-                                * (But conflicts between user-assigned names will cause
-                                * an error.)
-                                */
-                               if (ConstraintNameIsGenerated(check[i].ccname))
-                                       cdef->name = NULL;
-                               else
-                                       cdef->name = pstrdup(check[i].ccname);
+                               cdef->name = pstrdup(check[i].ccname);
                                cdef->raw_expr = NULL;
                                /* adjust varattnos of ccbin here */
                                expr = stringToNode(check[i].ccbin);
@@ -3610,10 +3597,11 @@ ATExecAddConstraint(AlteredTableInfo *tab, Relation rel, Node *newConstraint)
                        }
                        else
                                fkconstraint->constr_name =
-                                       GenerateConstraintName(CONSTRAINT_RELATION,
-                                                                                  RelationGetRelid(rel),
-                                                                                  RelationGetNamespace(rel),
-                                                                                  &tab->constr_name_ctr);
+                                       ChooseConstraintName(RelationGetRelationName(rel),
+                                                                                strVal(linitial(fkconstraint->fk_attrs)),
+                                                                                "fkey",
+                                                                                RelationGetNamespace(rel),
+                                                                                NIL);
 
                        ATAddForeignKeyConstraint(tab, rel, fkconstraint);
 
index 439ad91cc37e7d91eb9fe56cfcfc7c998f06c825..a64617d08d4f76b0bb840a7b9dba664bd50d1d93 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.58 2004/06/04 20:35:21 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.59 2004/06/10 17:55:56 tgl Exp $
  *
  * DESCRIPTION
  *       The "DefineFoo" routines take the parse tree and pick out the
@@ -83,7 +83,7 @@ static void domainOwnerCheck(HeapTuple tup, TypeName *typename);
 static char *domainAddConstraint(Oid domainOid, Oid domainNamespace,
                                        Oid baseTypeOid,
                                        int typMod, Constraint *constr,
-                                       int *counter, char *domainName);
+                                       char *domainName);
 
 
 /*
@@ -509,7 +509,6 @@ DefineDomain(CreateDomainStmt *stmt)
        Oid                     basetypeoid;
        Oid                     domainoid;
        Form_pg_type baseType;
-       int                     counter = 0;
 
        /* Convert list of names to a name and namespace */
        domainNamespace = QualifiedNameGetCreationNamespace(stmt->domainname,
@@ -760,7 +759,7 @@ DefineDomain(CreateDomainStmt *stmt)
                        case CONSTR_CHECK:
                                domainAddConstraint(domainoid, domainNamespace,
                                                                        basetypeoid, stmt->typename->typmod,
-                                                                       constr, &counter, domainName);
+                                                                       constr, domainName);
                                break;
 
                                /* Other constraint types were fully processed above */
@@ -768,6 +767,9 @@ DefineDomain(CreateDomainStmt *stmt)
                        default:
                                break;
                }
+
+               /* CCI so we can detect duplicate constraint names */
+               CommandCounterIncrement();
        }
 
        /*
@@ -1463,7 +1465,6 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
        char       *ccbin;
        Expr       *expr;
        ExprState  *exprstate;
-       int                     counter = 0;
        Constraint *constr;
 
        /* Make a TypeName so we can use standard type lookup machinery */
@@ -1547,7 +1548,7 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
 
        ccbin = domainAddConstraint(HeapTupleGetOid(tup), typTup->typnamespace,
                                                                typTup->typbasetype, typTup->typtypmod,
-                                                        constr, &counter, NameStr(typTup->typname));
+                                                               constr, NameStr(typTup->typname));
 
        /*
         * Test all values stored in the attributes based on the domain the
@@ -1788,7 +1789,7 @@ domainOwnerCheck(HeapTuple tup, TypeName *typename)
 static char *
 domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
                                        int typMod, Constraint *constr,
-                                       int *counter, char *domainName)
+                                       char *domainName)
 {
        Node       *expr;
        char       *ccsrc;
@@ -1811,10 +1812,11 @@ domainAddConstraint(Oid domainOid, Oid domainNamespace, Oid baseTypeOid,
                                        constr->name, domainName)));
        }
        else
-               constr->name = GenerateConstraintName(CONSTRAINT_DOMAIN,
-                                                                                         domainOid,
-                                                                                         domainNamespace,
-                                                                                         counter);
+               constr->name = ChooseConstraintName(domainName,
+                                                                                       NULL,
+                                                                                       "check",
+                                                                                       domainNamespace,
+                                                                                       NIL);
 
        /*
         * Convert the A_EXPR in raw_expr into an EXPR
index f6cdf96e296f77834f3766674108c2546972ff39..e5537e26ae99355426e6795a32ce14e444af28d4 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *     $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.304 2004/06/09 19:08:16 tgl Exp $
+ *     $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.305 2004/06/10 17:55:58 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,6 +20,7 @@
 #include "catalog/namespace.h"
 #include "catalog/pg_index.h"
 #include "catalog/pg_type.h"
+#include "commands/defrem.h"
 #include "commands/prepare.h"
 #include "miscadmin.h"
 #include "nodes/makefuncs.h"
@@ -45,7 +46,6 @@
 #include "utils/lsyscache.h"
 #include "utils/relcache.h"
 #include "utils/syscache.h"
-#include "mb/pg_wchar.h"
 
 
 /* State shared by transformCreateSchemaStmt and its subroutines */
@@ -703,90 +703,6 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt,
        return qry;
 }
 
-/*
- *     makeObjectName()
- *
- *     Create a name for an implicitly created index, sequence, constraint, etc.
- *
- *     The parameters are: the original table name, the original field name, and
- *     a "type" string (such as "seq" or "pkey").      The field name and/or type
- *     can be NULL if not relevant.
- *
- *     The result is a palloc'd string.
- *
- *     The basic result we want is "name1_name2_type", omitting "_name2" or
- *     "_type" when those parameters are NULL.  However, we must generate
- *     a name with less than NAMEDATALEN characters!  So, we truncate one or
- *     both names if necessary to make a short-enough string.  The type part
- *     is never truncated (so it had better be reasonably short).
- *
- *     To reduce the probability of collisions, we might someday add more
- *     smarts to this routine, like including some "hash" characters computed
- *     from the truncated characters.  Currently it seems best to keep it simple,
- *     so that the generated names are easily predictable by a person.
- */
-char *
-makeObjectName(const char *name1, const char *name2, const char *typename)
-{
-       char       *name;
-       int                     overhead = 0;   /* chars needed for type and underscores */
-       int                     availchars;             /* chars available for name(s) */
-       int                     name1chars;             /* chars allocated to name1 */
-       int                     name2chars;             /* chars allocated to name2 */
-       int                     ndx;
-
-       name1chars = strlen(name1);
-       if (name2)
-       {
-               name2chars = strlen(name2);
-               overhead++;                             /* allow for separating underscore */
-       }
-       else
-               name2chars = 0;
-       if (typename)
-               overhead += strlen(typename) + 1;
-
-       availchars = NAMEDATALEN - 1 - overhead;
-
-       /*
-        * If we must truncate,  preferentially truncate the longer name. This
-        * logic could be expressed without a loop, but it's simple and
-        * obvious as a loop.
-        */
-       while (name1chars + name2chars > availchars)
-       {
-               if (name1chars > name2chars)
-                       name1chars--;
-               else
-                       name2chars--;
-       }
-
-       if (name1)
-               name1chars = pg_mbcliplen(name1, name1chars, name1chars);
-       if (name2)
-               name2chars = pg_mbcliplen(name2, name2chars, name2chars);
-
-       /* Now construct the string using the chosen lengths */
-       name = palloc(name1chars + name2chars + overhead + 1);
-       strncpy(name, name1, name1chars);
-       ndx = name1chars;
-       if (name2)
-       {
-               name[ndx++] = '_';
-               strncpy(name + ndx, name2, name2chars);
-               ndx += name2chars;
-       }
-       if (typename)
-       {
-               name[ndx++] = '_';
-               strcpy(name + ndx, typename);
-       }
-       else
-               name[ndx] = '\0';
-
-       return name;
-}
-
 /*
  * transformCreateStmt -
  *       transforms the "create table" statement
@@ -919,21 +835,34 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
        /* Special actions for SERIAL pseudo-types */
        if (is_serial)
        {
-               char       *sname;
+               Oid                     snamespaceid;
                char       *snamespace;
+               char       *sname;
                char       *qstring;
                A_Const    *snamenode;
                FuncCall   *funccallnode;
                CreateSeqStmt *seqstmt;
 
                /*
-                * Determine name and namespace to use for the sequence.
+                * Determine namespace and name to use for the sequence.
+                *
+                * Although we use ChooseRelationName, it's not guaranteed that
+                * the selected sequence name won't conflict; given sufficiently
+                * long field names, two different serial columns in the same table
+                * could be assigned the same sequence name, and we'd not notice
+                * since we aren't creating the sequence quite yet.  In practice
+                * this seems quite unlikely to be a problem, especially since
+                * few people would need two serial columns in one table.
                 */
-               sname = makeObjectName(cxt->relation->relname, column->colname, "seq");
-               snamespace = get_namespace_name(RangeVarGetCreationNamespace(cxt->relation));
+               snamespaceid = RangeVarGetCreationNamespace(cxt->relation);
+               snamespace = get_namespace_name(snamespaceid);
+               sname = ChooseRelationName(cxt->relation->relname,
+                                                                  column->colname,
+                                                                  "seq",
+                                                                  snamespaceid);
 
                ereport(NOTICE,
-                               (errmsg("%s will create implicit sequence \"%s\" for \"serial\" column \"%s.%s\"",
+                               (errmsg("%s will create implicit sequence \"%s\" for serial column \"%s.%s\"",
                                                cxt->stmtType, sname,
                                                cxt->relation->relname, column->colname)));
 
@@ -975,7 +904,6 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
 
                constraint = makeNode(Constraint);
                constraint->contype = CONSTR_DEFAULT;
-               constraint->name = sname;
                constraint->raw_expr = (Node *) funccallnode;
                constraint->cooked_expr = NULL;
                constraint->keys = NIL;
@@ -1044,30 +972,13 @@ transformColumnDefinition(ParseState *pstate, CreateStmtContext *cxt,
                                break;
 
                        case CONSTR_PRIMARY:
-                               if (constraint->name == NULL)
-                                       constraint->name = makeObjectName(cxt->relation->relname,
-                                                                                                         NULL,
-                                                                                                         "pkey");
-                               if (constraint->keys == NIL)
-                                       constraint->keys = list_make1(makeString(column->colname));
-                               cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
-                               break;
-
                        case CONSTR_UNIQUE:
-                               if (constraint->name == NULL)
-                                       constraint->name = makeObjectName(cxt->relation->relname,
-                                                                                                         column->colname,
-                                                                                                         "key");
                                if (constraint->keys == NIL)
                                        constraint->keys = list_make1(makeString(column->colname));
                                cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
                                break;
 
                        case CONSTR_CHECK:
-                               if (constraint->name == NULL)
-                                       constraint->name = makeObjectName(cxt->relation->relname,
-                                                                                                         column->colname,
-                                                                                                         NULL);
                                cxt->ckconstraints = lappend(cxt->ckconstraints, constraint);
                                break;
 
@@ -1093,13 +1004,6 @@ transformTableConstraint(ParseState *pstate, CreateStmtContext *cxt,
        switch (constraint->contype)
        {
                case CONSTR_PRIMARY:
-                       if (constraint->name == NULL)
-                               constraint->name = makeObjectName(cxt->relation->relname,
-                                                                                                 NULL,
-                                                                                                 "pkey");
-                       cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
-                       break;
-
                case CONSTR_UNIQUE:
                        cxt->ixconstraints = lappend(cxt->ixconstraints, constraint);
                        break;
index fe836010ecf94d56b99773294a335620c6bc94f5..245b999205c6e88bccc70946ec638ddd2c45104a 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.10 2003/11/29 22:40:58 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_constraint.h,v 1.11 2004/06/10 17:55:59 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -141,15 +141,14 @@ typedef FormData_pg_constraint *Form_pg_constraint;
  */
 
 /*
- * Used for constraint support functions where the
- * and conrelid, contypid columns being looked up
+ * Identify constraint type for lookup purposes
  */
-typedef enum CONSTRAINTCATEGORY
+typedef enum ConstraintCategory
 {
        CONSTRAINT_RELATION,
        CONSTRAINT_DOMAIN,
-       CONSTRAINT_ASSERTION
-} CONSTRAINTCATEGORY;
+       CONSTRAINT_ASSERTION            /* for future expansion */
+} ConstraintCategory;
 
 /*
  * prototypes for functions in pg_constraint.c
@@ -176,10 +175,10 @@ extern Oid CreateConstraintEntry(const char *constraintName,
 
 extern void RemoveConstraintById(Oid conId);
 
-extern bool ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace,
-                                        const char *cname);
-extern char *GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace,
-                                          int *counter);
-extern bool ConstraintNameIsGenerated(const char *cname);
+extern bool ConstraintNameIsUsed(ConstraintCategory conCat, Oid objId,
+                                                                Oid objNamespace, const char *conname);
+extern char *ChooseConstraintName(const char *name1, const char *name2,
+                                                                 const char *label, Oid namespace,
+                                                                 List *others);
 
 #endif   /* PG_CONSTRAINT_H */
index 892aee34aedabbab568df5ea04f567980e5895a6..ba7415a582de997b7fdde80cd1557e7d5b17f471 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.56 2004/05/14 16:11:25 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/commands/defrem.h,v 1.57 2004/06/10 17:55:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,6 +35,10 @@ extern void RemoveIndex(RangeVar *relation, DropBehavior behavior);
 extern void ReindexIndex(RangeVar *indexRelation, bool force);
 extern void ReindexTable(RangeVar *relation, bool force);
 extern void ReindexDatabase(const char *databaseName, bool force, bool all);
+extern char *makeObjectName(const char *name1, const char *name2,
+                                                       const char *label);
+extern char *ChooseRelationName(const char *name1, const char *name2,
+                                                               const char *label, Oid namespace);
 
 /* commands/functioncmds.c */
 extern void CreateFunction(CreateFunctionStmt *stmt);
index 76c77025ece1a874a091891558b78ecb4d43b3d3..29784d041eacc4cd5570115ed6f1723cb40e86a6 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/parser/analyze.h,v 1.26 2004/05/05 04:48:47 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/parser/analyze.h,v 1.27 2004/06/10 17:56:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,10 +21,6 @@ extern List *parse_analyze_varparams(Node *parseTree, Oid **paramTypes,
                                                int *numParams);
 extern List *parse_sub_analyze(Node *parseTree, ParseState *parentParseState);
 extern List *analyzeCreateSchemaStmt(CreateSchemaStmt *stmt);
-
-extern char *makeObjectName(const char *name1, const char *name2,
-                                                       const char *typename);
-
 extern void CheckSelectForUpdate(Query *qry);
 
 #endif   /* ANALYZE_H */
index feb08520326a210268a54271accfe0e57a0bfa78..a8f81624fb2a3e6cfe5d9837937b70f814c931b7 100644 (file)
@@ -194,27 +194,27 @@ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" fo
 CREATE TEMP TABLE FKTABLE (ftest1 inet);
 -- This next should fail, because inet=int does not exist
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
 -- This should also fail for the same reason, but here we
 -- give the column name
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
 -- This should succeed, even though they are different types
 -- because varchar=int does exist
 DROP TABLE FKTABLE;
 CREATE TEMP TABLE FKTABLE (ftest1 varchar);
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
-WARNING:  foreign key constraint "$1" will require costly sequential scans
+WARNING:  foreign key constraint "fktable_ftest1_fkey" will require costly sequential scans
 DETAIL:  Key columns "ftest1" and "ptest1" are of different types: character varying and integer.
 -- As should this
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
-WARNING:  foreign key constraint "$2" will require costly sequential scans
+WARNING:  foreign key constraint "fktable_ftest1_fkey1" will require costly sequential scans
 DETAIL:  Key columns "ftest1" and "ptest1" are of different types: character varying and integer.
 DROP TABLE pktable cascade;
-NOTICE:  drop cascades to constraint $2 on table fktable
-NOTICE:  drop cascades to constraint $1 on table fktable
+NOTICE:  drop cascades to constraint fktable_ftest1_fkey1 on table fktable
+NOTICE:  drop cascades to constraint fktable_ftest1_fkey on table fktable
 DROP TABLE fktable;
 CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
                            PRIMARY KEY(ptest1, ptest2));
@@ -222,26 +222,26 @@ NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" fo
 -- This should fail, because we just chose really odd types
 CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp);
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2) references pktable;
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
 DROP TABLE FKTABLE;
 -- Again, so should this...
 CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 timestamp);
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
      references pktable(ptest1, ptest2);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
 DROP TABLE FKTABLE;
 -- This fails because we mixed up the column ordering
 CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet);
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
      references pktable(ptest2, ptest1);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet.
 -- As does this...
 ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1)
      references pktable(ptest1, ptest2);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest2_fkey" cannot be implemented
 DETAIL:  Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer.
 -- temp tables should go away by themselves, need not drop them.
 -- test check constraint adding
@@ -284,7 +284,7 @@ create table atacc1 (test int check (test>3), test2 int);
 alter table atacc1 add check (test2>test);
 -- should fail for $2
 insert into atacc1 (test2, test) values (3, 4);
-ERROR:  new row for relation "atacc1" violates check constraint "$1"
+ERROR:  new row for relation "atacc1" violates check constraint "atacc1_check"
 drop table atacc1;
 -- inheritance related tests
 create table atacc1 (test int);
@@ -1081,7 +1081,7 @@ alter table p1 add column f2 text;
 NOTICE:  merging definition of column "f2" for child "c1"
 insert into p1 values (1,2,'abc');
 insert into c1 values(11,'xyz',33,0); -- should fail
-ERROR:  new row for relation "c1" violates check constraint "p1_a1"
+ERROR:  new row for relation "c1" violates check constraint "c1_a1_check"
 insert into c1 values(11,'xyz',33,22);
 select * from p1;
  f1 | a1 | f2  
@@ -1100,7 +1100,7 @@ select * from p1;
 
 drop table p1 cascade;
 NOTICE:  drop cascades to table c1
-NOTICE:  drop cascades to constraint p1_a1 on table c1
+NOTICE:  drop cascades to constraint c1_a1_check on table c1
 -- test that operations with a dropped column do not try to reference
 -- its datatype
 create domain mytype as text;
@@ -1148,7 +1148,7 @@ ERROR:  column "f1" cannot be cast to type "pg_catalog.int4"
 alter table foo alter f1 TYPE varchar(10);
 create table anothertab (atcol1 serial8, atcol2 boolean,
        constraint anothertab_chk check (atcol1 <= 3));
-NOTICE:  CREATE TABLE will create implicit sequence "anothertab_atcol1_seq" for "serial" column "anothertab.atcol1"
+NOTICE:  CREATE TABLE will create implicit sequence "anothertab_atcol1_seq" for serial column "anothertab.atcol1"
 insert into anothertab (atcol1, atcol2) values (default, true);
 insert into anothertab (atcol1, atcol2) values (default, false);
 select * from anothertab;
index e5f2e4cda65d4f81ee303bf789245d7a35bb1fb6..7fa83a5723db502801cf22aa1bcb7672cc19ac2e 100644 (file)
@@ -3,14 +3,14 @@
 --
 CREATE TABLE clstr_tst_s (rf_a SERIAL PRIMARY KEY,
        b INT);
-NOTICE:  CREATE TABLE will create implicit sequence "clstr_tst_s_rf_a_seq" for "serial" column "clstr_tst_s.rf_a"
+NOTICE:  CREATE TABLE will create implicit sequence "clstr_tst_s_rf_a_seq" for serial column "clstr_tst_s.rf_a"
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "clstr_tst_s_pkey" for table "clstr_tst_s"
 CREATE TABLE clstr_tst (a SERIAL PRIMARY KEY,
        b INT,
        c TEXT,
        d TEXT,
        CONSTRAINT clstr_tst_con FOREIGN KEY (b) REFERENCES clstr_tst_s);
-NOTICE:  CREATE TABLE will create implicit sequence "clstr_tst_a_seq" for "serial" column "clstr_tst.a"
+NOTICE:  CREATE TABLE will create implicit sequence "clstr_tst_a_seq" for serial column "clstr_tst.a"
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "clstr_tst_pkey" for table "clstr_tst"
 CREATE INDEX clstr_tst_b ON clstr_tst (b);
 CREATE INDEX clstr_tst_c ON clstr_tst (c);
@@ -303,10 +303,10 @@ SELECT pg_class.relname FROM pg_index, pg_class, pg_class AS pg_class_2
 WHERE pg_class.oid=indexrelid
        AND indrelid=pg_class_2.oid
        AND pg_class_2.relname = 'clstr_tst'
-       AND indisclustered;
 relname 
- ---------
- (0 rows)
+       AND indisclustered;
+ relname 
+---------
+(0 rows)
 
 -- Verify that clustering all tables does in fact cluster the right ones
 CREATE USER clstr_user;
index 6048f9392fc39cb11868127e4291ba601669f572..f3da7e85c68b30f0ad241dee31ac53fe5f7641c2 100644 (file)
@@ -5,7 +5,7 @@ CREATE TABLE x (
        d text,
        e text
 );
-NOTICE:  CREATE TABLE will create implicit sequence "x_a_seq" for "serial" column "x.a"
+NOTICE:  CREATE TABLE will create implicit sequence "x_a_seq" for serial column "x.a"
 CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
   BEGIN
                NEW.e := ''before trigger fired''::text;
@@ -191,6 +191,6 @@ COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE '\\';
 "Jackson, Sam","\\h"
 "It is \"perfect\"."," "
 "",
-DROP TABLE x;
+DROP TABLE x, y;
 DROP FUNCTION fn_x_before();
 DROP FUNCTION fn_x_after();
index b23e84e7288a5ee1ecc160b67eab13c0f6257582..39929de2b3f926053d8abb4f199710f28830e78b 100644 (file)
@@ -116,7 +116,7 @@ INSERT INTO nulltest values ('a', 'b', 'c', 'd', 'c');  -- Good
 insert into nulltest values ('a', 'b', 'c', 'd', NULL);
 ERROR:  domain dcheck does not allow null values
 insert into nulltest values ('a', 'b', 'c', 'd', 'a');
-ERROR:  new row for relation "nulltest" violates check constraint "nulltest_col5"
+ERROR:  new row for relation "nulltest" violates check constraint "nulltest_col5_check"
 INSERT INTO nulltest values (NULL, 'b', 'c', 'd', 'd');
 ERROR:  domain dnotnull does not allow null values
 INSERT INTO nulltest values ('a', NULL, 'c', 'd', 'c');
@@ -130,7 +130,7 @@ ERROR:  domain dcheck does not allow null values
 CONTEXT:  COPY nulltest, line 1: "a    b       \N      d       \N"
 -- Last row is bad
 COPY nulltest FROM stdin;
-ERROR:  new row for relation "nulltest" violates check constraint "nulltest_col5"
+ERROR:  new row for relation "nulltest" violates check constraint "nulltest_col5_check"
 CONTEXT:  COPY nulltest, line 3: "a    b       c       \N      a"
 select * from nulltest;
  col1 | col2 | col3 | col4 | col5 
@@ -251,13 +251,13 @@ ERROR:  column "col1" of table "domcontest" contains values that violate the new
 alter domain con add constraint t check (VALUE < 34);
 alter domain con add check (VALUE > 0);
 insert into domcontest values (-5); -- fails
-ERROR:  value for domain con violates check constraint "$1"
+ERROR:  value for domain con violates check constraint "con_check"
 insert into domcontest values (42); -- fails
 ERROR:  value for domain con violates check constraint "t"
 insert into domcontest values (5);
 alter domain con drop constraint t;
 insert into domcontest values (-5); --fails
-ERROR:  value for domain con violates check constraint "$1"
+ERROR:  value for domain con violates check constraint "con_check"
 insert into domcontest values (42);
 -- Confirm ALTER DOMAIN with RULES.
 create table domtab (col1 integer);
index 5aae3720d3064d20d2e917d65d70bbfbd4c67717..3c9a7d6668df56b7b3468f674f6fcac185315267 100644 (file)
@@ -21,7 +21,7 @@ INSERT INTO FKTABLE VALUES (3, 4);
 INSERT INTO FKTABLE VALUES (NULL, 1);
 -- Insert a failed row into FK TABLE
 INSERT INTO FKTABLE VALUES (100, 2);
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
 DETAIL:  Key (ftest1)=(100) is not present in table "pktable".
 -- Check FKTABLE
 SELECT * FROM FKTABLE;
@@ -282,7 +282,7 @@ INSERT INTO FKTABLE VALUES (3, 4);
 INSERT INTO FKTABLE VALUES (NULL, 1);
 -- Insert a failed row into FK TABLE
 INSERT INTO FKTABLE VALUES (100, 2);
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
 DETAIL:  Key (ftest1)=(100) is not present in table "pktable".
 -- Check FKTABLE
 SELECT * FROM FKTABLE;
@@ -307,7 +307,7 @@ SELECT * FROM PKTABLE;
 
 -- Delete a row from PK TABLE (should fail)
 DELETE FROM PKTABLE WHERE ptest1=1;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "fktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "fktable_ftest1_fkey" on "fktable"
 DETAIL:  Key (ptest1)=(1) is still referenced from table "fktable".
 -- Delete a row from PK TABLE (should succeed)
 DELETE FROM PKTABLE WHERE ptest1=5;
@@ -323,7 +323,7 @@ SELECT * FROM PKTABLE;
 
 -- Update a row from PK TABLE (should fail)
 UPDATE PKTABLE SET ptest1=0 WHERE ptest1=2;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "fktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "fktable_ftest1_fkey" on "fktable"
 DETAIL:  Key (ptest1)=(2) is still referenced from table "fktable".
 -- Update a row from PK TABLE (should succeed)
 UPDATE PKTABLE SET ptest1=0 WHERE ptest1=4;
@@ -750,22 +750,22 @@ CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
 -- This next should fail, because inet=int does not exist
 CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
 -- This should also fail for the same reason, but here we
 -- give the column name
 CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: inet and integer.
 -- This should succeed (with a warning), even though they are different types
 -- because int=varchar does exist
 CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable);
-WARNING:  foreign key constraint "$1" will require costly sequential scans
+WARNING:  foreign key constraint "fktable_ftest1_fkey" will require costly sequential scans
 DETAIL:  Key columns "ftest1" and "ptest1" are of different types: character varying and integer.
 DROP TABLE FKTABLE;
 -- As should this
 CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable(ptest1));
-WARNING:  foreign key constraint "$1" will require costly sequential scans
+WARNING:  foreign key constraint "fktable_ftest1_fkey" will require costly sequential scans
 DETAIL:  Key columns "ftest1" and "ptest1" are of different types: character varying and integer.
 DROP TABLE FKTABLE;
 DROP TABLE PKTABLE;
@@ -774,23 +774,23 @@ CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2));
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
 -- This should fail, because we just chose really odd types
 CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
 -- Again, so should this...
 CREATE TABLE FKTABLE (ftest1 cidr, ftest2 timestamp, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: cidr and integer.
 -- This fails because we mixed up the column ordering
 CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest2_fkey" cannot be implemented
 DETAIL:  Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer.
 -- As does this...
 CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest2_fkey" cannot be implemented
 DETAIL:  Key columns "ftest2" and "ptest1" are of incompatible types: inet and integer.
 -- And again..
 CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest2" are of incompatible types: integer and inet.
 -- This works...
 CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
@@ -814,19 +814,19 @@ DROP TABLE PKTABLE;
 CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
 ptest4) REFERENCES pktable(ptest2, ptest1));
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_ptest3_fkey" cannot be implemented
 DETAIL:  Key columns "ptest3" and "ptest2" are of incompatible types: integer and inet.
 -- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types
 CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
 ptest3) REFERENCES pktable(ptest1, ptest2));
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_ptest4_fkey" cannot be implemented
 DETAIL:  Key columns "ptest4" and "ptest1" are of incompatible types: inet and integer.
 -- Not this one either... Same as the last one except we didn't defined the columns being referenced.
 CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
 ptest3) REFERENCES pktable);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_ptest4_fkey" cannot be implemented
 DETAIL:  Key columns "ptest4" and "ptest1" are of incompatible types: inet and integer.
 --
 -- Now some cases with inheritance
@@ -841,19 +841,19 @@ insert into pktable(base1) values (1);
 insert into pktable(base1) values (2);
 --  let's insert a non-existant fktable value
 insert into fktable(ftest1) values (3);
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
 DETAIL:  Key (ftest1)=(3) is not present in table "pktable".
 --  let's make a valid row for that
 insert into pktable(base1) values (3);
 insert into fktable(ftest1) values (3);
 -- let's try removing a row that should fail from pktable
 delete from pktable where base1>2;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "fktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "fktable_ftest1_fkey" on "fktable"
 DETAIL:  Key (base1)=(3) is still referenced from table "fktable".
 -- okay, let's try updating all of the base1 values to *4
 -- which should fail.
 update pktable set base1=base1*4;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "fktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "fktable_ftest1_fkey" on "fktable"
 DETAIL:  Key (base1)=(3) is still referenced from table "fktable".
 -- okay, let's try an update that should work.
 update pktable set base1=base1*4 where base1<3;
@@ -869,19 +869,19 @@ insert into pktable(base1, ptest1) values (1, 1);
 insert into pktable(base1, ptest1) values (2, 2);
 --  let's insert a non-existant fktable value
 insert into fktable(ftest1, ftest2) values (3, 1);
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
 DETAIL:  Key (ftest1,ftest2)=(3,1) is not present in table "pktable".
 --  let's make a valid row for that
 insert into pktable(base1,ptest1) values (3, 1);
 insert into fktable(ftest1, ftest2) values (3, 1);
 -- let's try removing a row that should fail from pktable
 delete from pktable where base1>2;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "fktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "fktable_ftest1_fkey" on "fktable"
 DETAIL:  Key (base1,ptest1)=(3,1) is still referenced from table "fktable".
 -- okay, let's try updating all of the base1 values to *4
 -- which should fail.
 update pktable set base1=base1*4;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "fktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "fktable_ftest1_fkey" on "fktable"
 DETAIL:  Key (base1,ptest1)=(3,1) is still referenced from table "fktable".
 -- okay, let's try an update that should work.
 update pktable set base1=base1*4 where base1<3;
@@ -902,15 +902,15 @@ insert into pktable (base1, ptest1, base2, ptest2) values (2, 2, 2, 1);
 insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2);
 -- fails (3,2) isn't in base1, ptest1
 insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2);
-ERROR:  insert or update on table "pktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "pktable" violates foreign key constraint "pktable_base2_fkey"
 DETAIL:  Key (base2,ptest2)=(3,2) is not present in table "pktable".
 -- fails (2,2) is being referenced
 delete from pktable where base1=2;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "pktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "pktable_base2_fkey" on "pktable"
 DETAIL:  Key (base1,ptest1)=(2,2) is still referenced from table "pktable".
 -- fails (1,1) is being referenced (twice)
 update pktable set base1=3 where base1=1;
-ERROR:  update or delete on "pktable" violates foreign key constraint "$1" on "pktable"
+ERROR:  update or delete on "pktable" violates foreign key constraint "pktable_base2_fkey" on "pktable"
 DETAIL:  Key (base1,ptest1)=(1,1) is still referenced from table "pktable".
 -- this sequence of two deletes will work, since after the first there will be no (2,*) references
 delete from pktable where base2=2;
@@ -923,20 +923,20 @@ create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
 -- just generally bad types (with and without column references on the referenced table)
 create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "base1" are of incompatible types: cidr and integer.
 create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "base1" are of incompatible types: cidr and integer.
 -- let's mix up which columns reference which
 create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable);
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest2_fkey" cannot be implemented
 DETAIL:  Key columns "ftest2" and "base1" are of incompatible types: inet and integer.
 create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest2_fkey" cannot be implemented
 DETAIL:  Key columns "ftest2" and "base1" are of incompatible types: inet and integer.
 create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "fktable_ftest1_fkey" cannot be implemented
 DETAIL:  Key columns "ftest1" and "ptest1" are of incompatible types: integer and inet.
 drop table pktable;
 drop table pktable_base;
@@ -945,22 +945,22 @@ create table pktable_base(base1 int not null, base2 int);
 create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references
                                              pktable(base1, ptest1)) inherits (pktable_base);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_base2_fkey" cannot be implemented
 DETAIL:  Key columns "ptest2" and "ptest1" are of incompatible types: inet[] and inet.
 create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references
                                              pktable(ptest1, base1)) inherits (pktable_base);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_base2_fkey" cannot be implemented
 DETAIL:  Key columns "base2" and "ptest1" are of incompatible types: integer and inet.
 create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
                                              pktable(base1, ptest1)) inherits (pktable_base);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_ptest2_fkey" cannot be implemented
 DETAIL:  Key columns "ptest2" and "base1" are of incompatible types: inet and integer.
 create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
                                              pktable(base1, ptest1)) inherits (pktable_base);
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "pktable_pkey" for table "pktable"
-ERROR:  foreign key constraint "$1" cannot be implemented
+ERROR:  foreign key constraint "pktable_ptest2_fkey" cannot be implemented
 DETAIL:  Key columns "ptest2" and "base1" are of incompatible types: inet and integer.
 drop table pktable;
 ERROR:  table "pktable" does not exist
@@ -982,7 +982,7 @@ CREATE TABLE fktable (
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "fktable_pkey" for table "fktable"
 -- default to immediate: should fail
 INSERT INTO fktable VALUES (5, 10);
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
 DETAIL:  Key (fk)=(10) is not present in table "pktable".
 -- explicitely defer the constraint
 BEGIN;
@@ -1012,7 +1012,7 @@ BEGIN;
 SET CONSTRAINTS ALL IMMEDIATE;
 -- should fail
 INSERT INTO fktable VALUES (500, 1000);
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
 DETAIL:  Key (fk)=(1000) is not present in table "pktable".
 COMMIT;
 DROP TABLE fktable, pktable;
@@ -1036,7 +1036,7 @@ SET CONSTRAINTS ALL DEFERRED;
 INSERT INTO fktable VALUES (1000, 2000);
 -- should cause transaction abort, due to preceding error
 SET CONSTRAINTS ALL IMMEDIATE;
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
 DETAIL:  Key (fk)=(2000) is not present in table "pktable".
 INSERT INTO pktable VALUES (2000, 3); -- too late
 ERROR:  current transaction is aborted, commands ignored until end of transaction block
@@ -1058,7 +1058,7 @@ BEGIN;
 INSERT INTO fktable VALUES (100, 200);
 -- error here on commit
 COMMIT;
-ERROR:  insert or update on table "fktable" violates foreign key constraint "$1"
+ERROR:  insert or update on table "fktable" violates foreign key constraint "fktable_fk_fkey"
 DETAIL:  Key (fk)=(200) is not present in table "pktable".
 -- test notice about expensive referential integrity checks,
 -- where the index cannot be used because of type incompatibilities.
index 60e3a82ea34a38f86ba69624bc06bd25bf53c027..646bb639798e777615b41273bd64b8382c10a3ad 100644 (file)
@@ -9,7 +9,7 @@ CREATE SCHEMA test_schema_1
               a serial,
               b int UNIQUE
        );
-NOTICE:  CREATE TABLE will create implicit sequence "abc_a_seq" for "serial" column "abc.a"
+NOTICE:  CREATE TABLE will create implicit sequence "abc_a_seq" for serial column "abc.a"
 NOTICE:  CREATE TABLE / UNIQUE will create implicit index "abc_b_key" for table "abc"
 -- verify that the objects were created
 SELECT COUNT(*) FROM pg_class WHERE relnamespace =
index cb181bd6ba4a6740c2e52b239f8e0957a023d8a5..92548e6f925a44eddd373db8473f583c24b09fb5 100644 (file)
@@ -1408,10 +1408,10 @@ insert into rule_and_refint_t3 values (1, 11, 12, 'row2');
 insert into rule_and_refint_t3 values (1, 12, 11, 'row3');
 insert into rule_and_refint_t3 values (1, 12, 12, 'row4');
 insert into rule_and_refint_t3 values (1, 11, 13, 'row5');
-ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "$2"
+ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey1"
 DETAIL:  Key (id3a,id3c)=(1,13) is not present in table "rule_and_refint_t2".
 insert into rule_and_refint_t3 values (1, 13, 11, 'row6');
-ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "$1"
+ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey"
 DETAIL:  Key (id3a,id3b)=(1,13) is not present in table "rule_and_refint_t1".
 create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3
        where (exists (select 1 from rule_and_refint_t3
@@ -1423,8 +1423,8 @@ create rule rule_and_refint_t3_ins as on insert to rule_and_refint_t3
        and (rule_and_refint_t3.id3b = new.id3b))
        and (rule_and_refint_t3.id3c = new.id3c));
 insert into rule_and_refint_t3 values (1, 11, 13, 'row7');
-ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "$2"
+ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey1"
 DETAIL:  Key (id3a,id3c)=(1,13) is not present in table "rule_and_refint_t2".
 insert into rule_and_refint_t3 values (1, 13, 11, 'row8');
-ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "$1"
+ERROR:  insert or update on table "rule_and_refint_t3" violates foreign key constraint "rule_and_refint_t3_id3a_fkey"
 DETAIL:  Key (id3a,id3b)=(1,13) is not present in table "rule_and_refint_t1".
index d09e5db1701fc65a3d235e925405c90e637fd7b0..040506d4debd509a740667a0ceca367736bedbe5 100644 (file)
@@ -3,7 +3,7 @@
 ---
  
 CREATE TABLE serialTest (f1 text, f2 serial);
-NOTICE:  CREATE TABLE will create implicit sequence "serialtest_f2_seq" for "serial" column "serialtest.f2"
+NOTICE:  CREATE TABLE will create implicit sequence "serialtest_f2_seq" for serial column "serialtest.f2"
  
 INSERT INTO serialTest VALUES ('foo');
 INSERT INTO serialTest VALUES ('bar');
index 5e7d81d7732ed1628c68a4574370834f21c13c29..a3a00502512d38096ff2ab817def91b87a26fa47 100644 (file)
@@ -41,7 +41,7 @@ SELECT * FROM truncate_a;
 
 TRUNCATE truncate_a;
 ERROR:  cannot truncate a table referenced in a foreign key constraint
-DETAIL:  Table "truncate_b" references "truncate_a" via foreign key constraint "$1".
+DETAIL:  Table "truncate_b" references "truncate_a" via foreign key constraint "truncate_b_col1_fkey".
 SELECT * FROM truncate_a;
  col1 
 ------
index 2237e0c59661a9866ddc4b828b8c6837f315b393..70ab60ac40013ffbaa28741807e64f85c76c1f05 100644 (file)
@@ -127,7 +127,7 @@ INSERT INTO INSERT_TBL(y) VALUES ('Y');
 ERROR:  new row for relation "insert_tbl" violates check constraint "insert_con"
 INSERT INTO INSERT_TBL(y) VALUES ('Y');
 INSERT INTO INSERT_TBL(x,z) VALUES (1, -2);
-ERROR:  new row for relation "insert_tbl" violates check constraint "$1"
+ERROR:  new row for relation "insert_tbl" violates check constraint "insert_tbl_check"
 INSERT INTO INSERT_TBL(z,x) VALUES (-7,  7);
 INSERT INTO INSERT_TBL VALUES (5, 'check failed', -5);
 ERROR:  new row for relation "insert_tbl" violates check constraint "insert_con"
@@ -143,7 +143,7 @@ SELECT '' AS four, * FROM INSERT_TBL;
 (4 rows)
 
 INSERT INTO INSERT_TBL(y,z) VALUES ('check failed', 4);
-ERROR:  new row for relation "insert_tbl" violates check constraint "$1"
+ERROR:  new row for relation "insert_tbl" violates check constraint "insert_tbl_check"
 INSERT INTO INSERT_TBL(x,y) VALUES (5, 'check failed');
 ERROR:  new row for relation "insert_tbl" violates check constraint "insert_con"
 INSERT INTO INSERT_TBL(x,y) VALUES (5, '!check failed');
@@ -197,9 +197,9 @@ CREATE TABLE INSERT_CHILD (cx INT default 42,
        INHERITS (INSERT_TBL);
 INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,11);
 INSERT INTO INSERT_CHILD(x,z,cy) VALUES (7,-7,6);
-ERROR:  new row for relation "insert_child" violates check constraint "insert_child_cy"
+ERROR:  new row for relation "insert_child" violates check constraint "insert_child_check"
 INSERT INTO INSERT_CHILD(x,z,cy) VALUES (6,-7,7);
-ERROR:  new row for relation "insert_child" violates check constraint "$1"
+ERROR:  new row for relation "insert_child" violates check constraint "insert_tbl_check"
 INSERT INTO INSERT_CHILD(x,y,z,cy) VALUES (6,'check failed',-6,7);
 ERROR:  new row for relation "insert_child" violates check constraint "insert_con"
 SELECT * FROM INSERT_CHILD;
index 35c376d1e3c0ad9cf82ebbc54709bdb8d8e2457b..70c8ea6b1e809d84f4c32eabc23af36e6277981d 100644 (file)
@@ -129,6 +129,6 @@ COPY y TO stdout WITH CSV;
 COPY y TO stdout WITH CSV QUOTE '''' DELIMITER '|';
 COPY y TO stdout WITH CSV FORCE QUOTE col2 ESCAPE '\\';
 
-DROP TABLE x;
+DROP TABLE x, y;
 DROP FUNCTION fn_x_before();
 DROP FUNCTION fn_x_after();