Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3ce054b

Browse files
author
Thomas G. Lockhart
committed
Fix problem with multiple indices defined if using column- and table-
constraints. Reported by Tom Lane. Now, check for duplicate indices and retain the one which is a primary-key. Adjust elog NOTICE messages to surround table and column names with single quotes.
1 parent 575c40a commit 3ce054b

File tree

1 file changed

+68
-24
lines changed

1 file changed

+68
-24
lines changed

src/backend/parser/analyze.c

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 1994, Regents of the University of California
77
*
8-
* $Id: analyze.c,v 1.101 1999/02/23 07:44:44 thomas Exp $
8+
* $Id: analyze.c,v 1.102 1999/05/12 07:17:18 thomas Exp $
99
*
1010
*-------------------------------------------------------------------------
1111
*/
@@ -513,7 +513,6 @@ static Query *
513513
transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
514514
{
515515
Query *q;
516-
int have_pkey = FALSE;
517516
List *elements;
518517
Node *element;
519518
List *columns;
@@ -524,9 +523,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
524523
Constraint *constraint;
525524
List *keys;
526525
Ident *key;
527-
List *blist = NIL;
528-
List *ilist = NIL;
529-
IndexStmt *index;
526+
List *blist = NIL; /* "before list" of things to do before creating the table */
527+
List *ilist = NIL; /* "index list" of things to do after creating the table */
528+
IndexStmt *index, *pkey = NULL;
530529
IndexElem *iparam;
531530

532531
q = makeNode(Query);
@@ -568,6 +567,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
568567
constraint->def = cstring;
569568
constraint->keys = NULL;
570569

570+
#if 0
571571
/* The parser only allows PRIMARY KEY as a constraint for the SERIAL type.
572572
* So, if there is a constraint of any kind, assume it is that.
573573
* If PRIMARY KEY is specified, then don't need to gin up a UNIQUE constraint
@@ -580,7 +580,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
580580
}
581581
else
582582
{
583-
column->constraints = lcons(constraint, NIL);
583+
#endif
584+
column->constraints = lappend(column->constraints, constraint);
584585

585586
constraint = makeNode(Constraint);
586587
constraint->contype = CONSTR_UNIQUE;
@@ -590,13 +591,15 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
590591
"\n\tSum of lengths of '%s' and '%s' must be less than %d",
591592
NAMEDATALEN, stmt->relname, column->colname, (NAMEDATALEN-5));
592593
column->constraints = lappend(column->constraints, constraint);
594+
#if 0
593595
}
596+
#endif
594597

595598
sequence = makeNode(CreateSeqStmt);
596599
sequence->seqname = pstrdup(sname);
597600
sequence->options = NIL;
598601

599-
elog(NOTICE, "CREATE TABLE will create implicit sequence %s for SERIAL column %s.%s",
602+
elog(NOTICE, "CREATE TABLE will create implicit sequence '%s' for SERIAL column '%s.%s'",
600603
sequence->seqname, stmt->relname, column->colname);
601604

602605
blist = lcons(sequence, NIL);
@@ -735,40 +738,38 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
735738
while (dlist != NIL)
736739
{
737740
constraint = lfirst(dlist);
738-
if (nodeTag(constraint) != T_Constraint)
739-
elog(ERROR, "parser: unrecognized deferred node (internal error)", NULL);
741+
Assert(nodeTag(constraint) == T_Constraint);
742+
Assert((constraint->contype == CONSTR_PRIMARY)
743+
|| (constraint->contype == CONSTR_UNIQUE));
740744

741-
if (constraint->contype == CONSTR_PRIMARY)
745+
index = makeNode(IndexStmt);
746+
747+
index->unique = TRUE;
748+
index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE:FALSE);
749+
if (index->primary)
742750
{
743-
if (have_pkey)
751+
if (pkey != NULL)
744752
elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple primary keys"
745753
" for table %s are not legal", stmt->relname);
746-
else
747-
have_pkey = TRUE;
754+
pkey = (IndexStmt *) index;
748755
}
749-
else if (constraint->contype != CONSTR_UNIQUE)
750-
elog(ERROR, "parser: unrecognized deferred constraint (internal error)", NULL);
751756

752-
index = makeNode(IndexStmt);
753-
754-
index->unique = TRUE;
755-
index->primary = (constraint->contype == CONSTR_PRIMARY ? TRUE:FALSE);
756757
if (constraint->name != NULL)
758+
{
757759
index->idxname = constraint->name;
760+
}
758761
else if (constraint->contype == CONSTR_PRIMARY)
759762
{
760-
if (have_pkey)
761-
elog(ERROR, "CREATE TABLE/PRIMARY KEY multiple keys for table %s are not legal", stmt->relname);
762-
763-
have_pkey = TRUE;
764763
index->idxname = makeTableName(stmt->relname, "pkey", NULL);
765764
if (index->idxname == NULL)
766765
elog(ERROR, "CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
767766
"\n\tLength of '%s' must be less than %d",
768767
NAMEDATALEN, stmt->relname, (NAMEDATALEN-5));
769768
}
770769
else
770+
{
771771
index->idxname = NULL;
772+
}
772773

773774
index->relname = stmt->relname;
774775
index->accessMethod = "btree";
@@ -812,15 +813,58 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
812813
if (index->idxname == NULL)
813814
elog(ERROR, "CREATE TABLE unable to construct implicit index for table %s"
814815
"; name too long", stmt->relname);
816+
#if 0
815817
else
816-
elog(NOTICE, "CREATE TABLE/%s will create implicit index %s for table %s",
818+
elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
817819
((constraint->contype == CONSTR_PRIMARY) ? "PRIMARY KEY" : "UNIQUE"),
818820
index->idxname, stmt->relname);
821+
#endif
819822

820823
ilist = lappend(ilist, index);
821824
dlist = lnext(dlist);
822825
}
823826

827+
/* OK, now finally, if there is a primary key, then make sure that there aren't any redundant
828+
* unique indices defined on columns. This can arise if someone specifies UNIQUE explicitly
829+
* or if a SERIAL column was defined along with a table PRIMARY KEY constraint.
830+
* - thomas 1999-05-11
831+
*/
832+
if ((pkey != NULL) && (length(lfirst(pkey->indexParams)) == 1))
833+
{
834+
dlist = ilist;
835+
ilist = NIL;
836+
while (dlist != NIL)
837+
{
838+
int keep = TRUE;
839+
840+
index = lfirst(dlist);
841+
842+
/* has a single column argument, so might be a conflicting index... */
843+
if ((index != pkey)
844+
&& (length(index->indexParams) == 1))
845+
{
846+
char *pname = ((IndexElem *) lfirst(index->indexParams))->name;
847+
char *iname = ((IndexElem *) lfirst(index->indexParams))->name;
848+
/* same names? then don't keep... */
849+
keep = (strcmp(iname, pname) != 0);
850+
}
851+
852+
if (keep)
853+
ilist = lappend(ilist, index);
854+
dlist = lnext(dlist);
855+
}
856+
}
857+
858+
dlist = ilist;
859+
while (dlist != NIL)
860+
{
861+
index = lfirst(dlist);
862+
elog(NOTICE, "CREATE TABLE/%s will create implicit index '%s' for table '%s'",
863+
(index->primary? "PRIMARY KEY": "UNIQUE"),
864+
index->idxname, stmt->relname);
865+
dlist = lnext(dlist);
866+
}
867+
824868
q->utilityStmt = (Node *) stmt;
825869
extras_before = blist;
826870
extras_after = ilist;

0 commit comments

Comments
 (0)