From 2ac4cf55021220afbe04a08117cc842809e4693d Mon Sep 17 00:00:00 2001 From: "Thomas G. Lockhart" Date: Tue, 9 Dec 1997 01:44:14 +0000 Subject: [PATCH] Add information message about implicitly created indices. Check for duplicate implicit index names and generate unique names. --- src/backend/parser/analyze.c | 88 ++++++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 63b990aa74..b5700fcf69 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -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); }