5
5
*
6
6
* Copyright (c) 1994, Regents of the University of California
7
7
*
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 $
9
9
*
10
10
*-------------------------------------------------------------------------
11
11
*/
@@ -513,7 +513,6 @@ static Query *
513
513
transformCreateStmt (ParseState * pstate , CreateStmt * stmt )
514
514
{
515
515
Query * q ;
516
- int have_pkey = FALSE;
517
516
List * elements ;
518
517
Node * element ;
519
518
List * columns ;
@@ -524,9 +523,9 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
524
523
Constraint * constraint ;
525
524
List * keys ;
526
525
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 ;
530
529
IndexElem * iparam ;
531
530
532
531
q = makeNode (Query );
@@ -568,6 +567,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
568
567
constraint -> def = cstring ;
569
568
constraint -> keys = NULL ;
570
569
570
+ #if 0
571
571
/* The parser only allows PRIMARY KEY as a constraint for the SERIAL type.
572
572
* So, if there is a constraint of any kind, assume it is that.
573
573
* If PRIMARY KEY is specified, then don't need to gin up a UNIQUE constraint
@@ -580,7 +580,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
580
580
}
581
581
else
582
582
{
583
- column -> constraints = lcons (constraint , NIL );
583
+ #endif
584
+ column -> constraints = lappend (column -> constraints , constraint );
584
585
585
586
constraint = makeNode (Constraint );
586
587
constraint -> contype = CONSTR_UNIQUE ;
@@ -590,13 +591,15 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
590
591
"\n\tSum of lengths of '%s' and '%s' must be less than %d" ,
591
592
NAMEDATALEN , stmt -> relname , column -> colname , (NAMEDATALEN - 5 ));
592
593
column -> constraints = lappend (column -> constraints , constraint );
594
+ #if 0
593
595
}
596
+ #endif
594
597
595
598
sequence = makeNode (CreateSeqStmt );
596
599
sequence -> seqname = pstrdup (sname );
597
600
sequence -> options = NIL ;
598
601
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' " ,
600
603
sequence -> seqname , stmt -> relname , column -> colname );
601
604
602
605
blist = lcons (sequence , NIL );
@@ -735,40 +738,38 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
735
738
while (dlist != NIL )
736
739
{
737
740
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 ));
740
744
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 )
742
750
{
743
- if (have_pkey )
751
+ if (pkey != NULL )
744
752
elog (ERROR , "CREATE TABLE/PRIMARY KEY multiple primary keys"
745
753
" for table %s are not legal" , stmt -> relname );
746
- else
747
- have_pkey = TRUE;
754
+ pkey = (IndexStmt * ) index ;
748
755
}
749
- else if (constraint -> contype != CONSTR_UNIQUE )
750
- elog (ERROR , "parser: unrecognized deferred constraint (internal error)" , NULL );
751
756
752
- index = makeNode (IndexStmt );
753
-
754
- index -> unique = TRUE;
755
- index -> primary = (constraint -> contype == CONSTR_PRIMARY ? TRUE:FALSE);
756
757
if (constraint -> name != NULL )
758
+ {
757
759
index -> idxname = constraint -> name ;
760
+ }
758
761
else if (constraint -> contype == CONSTR_PRIMARY )
759
762
{
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;
764
763
index -> idxname = makeTableName (stmt -> relname , "pkey" , NULL );
765
764
if (index -> idxname == NULL )
766
765
elog (ERROR , "CREATE TABLE/PRIMARY KEY implicit index name must be less than %d characters"
767
766
"\n\tLength of '%s' must be less than %d" ,
768
767
NAMEDATALEN , stmt -> relname , (NAMEDATALEN - 5 ));
769
768
}
770
769
else
770
+ {
771
771
index -> idxname = NULL ;
772
+ }
772
773
773
774
index -> relname = stmt -> relname ;
774
775
index -> accessMethod = "btree" ;
@@ -812,15 +813,58 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
812
813
if (index -> idxname == NULL )
813
814
elog (ERROR , "CREATE TABLE unable to construct implicit index for table %s"
814
815
"; name too long" , stmt -> relname );
816
+ #if 0
815
817
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' " ,
817
819
((constraint -> contype == CONSTR_PRIMARY ) ? "PRIMARY KEY" : "UNIQUE" ),
818
820
index -> idxname , stmt -> relname );
821
+ #endif
819
822
820
823
ilist = lappend (ilist , index );
821
824
dlist = lnext (dlist );
822
825
}
823
826
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
+
824
868
q -> utilityStmt = (Node * ) stmt ;
825
869
extras_before = blist ;
826
870
extras_after = ilist ;
0 commit comments