OSDN Git Service

Add information message about implicitly created indices.
authorThomas G. Lockhart <lockhart@fourpalms.org>
Tue, 9 Dec 1997 01:44:14 +0000 (01:44 +0000)
committerThomas G. Lockhart <lockhart@fourpalms.org>
Tue, 9 Dec 1997 01:44:14 +0000 (01:44 +0000)
Check for duplicate implicit index names and generate unique names.

src/backend/parser/analyze.c

index 63b990a..b5700fc 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.52 1997/12/04 23:07:18 thomas Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.53 1997/12/09 01:44:14 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -366,6 +366,57 @@ makeTableName(void *elem,...)
        return (name);
 } /* makeTableName() */
 
+char *
+CreateIndexName(char *tname, char *cname, char *label, List *indices);
+
+char *
+CreateIndexName(char *tname, char *cname, char *label, List *indices)
+{
+       int                     pass = 0;
+       char       *iname = NULL;
+       List       *ilist;
+       IndexStmt  *index;
+       char            name2[NAMEDATALEN+1];
+
+       /* use working storage, since we might be trying several possibilities */
+       strcpy(name2,cname);
+       while (iname == NULL)
+       {
+               iname = makeTableName(tname, name2, label, NULL);
+               /* unable to make a name at all? then quit */
+               if (iname == NULL)
+                       break;
+
+#if PARSEDEBUG
+printf("CreateNameIndex- check %s against indices\n",iname);
+#endif
+
+               ilist = indices;
+               while (ilist != NIL)
+               {
+                       index = lfirst(ilist);
+#if PARSEDEBUG
+printf("CreateNameIndex- compare %s with existing index %s\n",iname,index->idxname);
+#endif
+                       if (strcasecmp(iname,index->idxname) == 0)
+                               break;
+
+                       ilist = lnext(ilist);
+               }
+               /* ran through entire list? then no name conflict found so done */
+               if (ilist == NIL)
+                       break;
+
+               /* the last one conflicted, so try a new name component */
+               pfree(iname);
+               iname = NULL;
+               pass++;
+               sprintf(name2, "%s_%d", cname, (pass+1));
+       }
+
+       return (iname);
+} /* CreateIndexName() */
+
 /*
  * transformCreateStmt -
  *       transforms the "create table" statement
@@ -379,6 +430,7 @@ static Query *
 transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
 {
        Query      *q;
+       int                     have_pkey = FALSE;
        List       *elements;
        Node       *element;
        List       *columns;
@@ -541,9 +593,9 @@ printf("transformCreateStmt- found CHECK clause\n");
  * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
  *
  * Note that this code does not currently look for all possible redundant cases
- *  and either ignore or stop with warning. The create will fail later when
- *  names for indices turn out to be redundant, or a user might just find
- *  extra useless indices which might kill performance. - thomas 1997-12-04
+ *  and either ignore or stop with warning. The create might fail later when
+ *  names for indices turn out to be redundant, or a user might have specified
+ *  extra useless indices which might hurt performance. - thomas 1997-12-08
  */
        ilist = NIL;
        while (dlist != NIL)
@@ -552,27 +604,38 @@ printf("transformCreateStmt- found CHECK clause\n");
                if (nodeTag(constraint) != T_Constraint)
                        elog(WARN,"parser: internal error; unrecognized deferred node",NULL);
 
-               if ((constraint->contype != CONSTR_PRIMARY)
-                && (constraint->contype != CONSTR_UNIQUE))
-                       elog(WARN,"parser: internal error; illegal deferred constraint",NULL);
-
 #if PARSEDEBUG
 printf("transformCreateStmt- found deferred constraint %s\n",
  ((constraint->name != NULL)? constraint->name: "(unknown)"));
 #endif
 
+               if (constraint->contype == CONSTR_PRIMARY)
+                       if (have_pkey)
+                               elog(WARN,"CREATE TABLE/PRIMARY KEY multiple primary keys"
+                                       " for table %s are not legal", stmt->relname);
+                       else 
+                               have_pkey = TRUE;
+               else if (constraint->contype != CONSTR_UNIQUE)
+                       elog(WARN,"parser: internal error; unrecognized deferred constraint",NULL);
+
 #if PARSEDEBUG
 printf("transformCreateStmt- found deferred %s clause\n",
  (constraint->contype == CONSTR_PRIMARY? "PRIMARY KEY": "UNIQUE"));
 #endif
+
                index = makeNode(IndexStmt);
-               ilist = lappend(ilist, index);
 
                index->unique = TRUE;
                if (constraint->name != NULL)
                        index->idxname = constraint->name;
                else if (constraint->contype == CONSTR_PRIMARY)
+               {
+                       if (have_pkey)
+                               elog(WARN,"CREATE TABLE/PRIMARY KEY multiple keys for table %s are not legal", stmt->relname);
+
+                       have_pkey = TRUE;
                        index->idxname = makeTableName(stmt->relname, "pkey", NULL);
+               }
                else
                        index->idxname = NULL;
 
@@ -619,7 +682,7 @@ printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname);
                        index->indexParams = lappend(index->indexParams, iparam);
 
                        if (index->idxname == NULL)
-                               index->idxname = makeTableName(stmt->relname, iparam->name, "key", NULL);
+                               index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
 
                        keys = lnext(keys);
                }
@@ -627,7 +690,12 @@ printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname);
                if (index->idxname == NULL)
                        elog(WARN,"parser: unable to construct implicit index for table %s"
                                "; name too long", stmt->relname);
+               else
+                       elog(NOTICE,"CREATE TABLE/%s will create implicit index %s for table %s",
+                               ((constraint->contype == CONSTR_PRIMARY)? "PRIMARY KEY": "UNIQUE"),
+                               index->idxname, stmt->relname);
 
+               ilist = lappend(ilist, index);
                dlist = lnext(dlist);
        }