66 * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
77 * Portions Copyright (c) 1994, Regents of the University of California
88 *
9- *$Id: analyze.c,v 1.172 2000/12/07 01:12:08 tgl Exp $
9+ *$Id: analyze.c,v 1.173 2000/12/18 01:37:56 tgl Exp $
1010 *
1111 *-------------------------------------------------------------------------
1212 */
@@ -945,9 +945,10 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
945945index -> withClause = NIL ;
946946index -> whereClause = NULL ;
947947
948- foreach (keys ,constraint -> keys )
948+ foreach (keys ,constraint -> keys )
949949{
950- int found = 0 ;
950+ bool found = false;
951+
951952key = (Ident * )lfirst (keys );
952953Assert (IsA (key ,Ident ));
953954column = NULL ;
@@ -956,26 +957,58 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
956957column = lfirst (columns );
957958Assert (IsA (column ,ColumnDef ));
958959if (strcmp (column -> colname ,key -> name )== 0 )
960+ {
961+ found = true;
959962break ;
963+ }
964+ }
965+ if (found )
966+ {
967+ /* found column in the new table; force it to be NOT NULL */
968+ if (constraint -> contype == CONSTR_PRIMARY )
969+ column -> is_not_null = TRUE;
960970}
961- if (columns == NIL ) {/* try inherited tables */
971+ else
972+ {
973+ /* try inherited tables */
974+ List * inhRelnames = stmt -> inhRelnames ;
962975List * inher ;
963- List * inhRelnames = stmt -> inhRelnames ;
964- Relation rel ;
965- foreach ( inher , inhRelnames ) {
966- int count = 0 ;
967- Value * inh = lfirst ( inher ) ;
968- if ( inh -> type != T_String ) {
969- elog ( ERROR , "inherited table name list returns a non-string" );
970- }
971- rel = heap_openr (inh -> val .str ,AccessShareLock );
976+
977+ foreach ( inher , inhRelnames )
978+ {
979+ Value * inh = lfirst ( inher ) ;
980+ Relation rel ;
981+ int count ;
982+
983+ Assert ( IsA ( inh , String ));
984+ rel = heap_openr (inh -> val .str ,AccessShareLock );
972985if (rel -> rd_rel -> relkind != RELKIND_RELATION )
973986elog (ERROR ,"inherited table \"%s\" is not a relation" ,
974- inh -> val .str );
975- for (;count < rel -> rd_att -> natts ;count ++ ) {
976- char * name = NameStr (rel -> rd_att -> attrs [count ]-> attname );
977- if (strcmp (key -> name ,name )== 0 ) {
978- found = 1 ;
987+ inh -> val .str );
988+ for (count = 0 ;count < rel -> rd_att -> natts ;count ++ )
989+ {
990+ Form_pg_attribute inhattr = rel -> rd_att -> attrs [count ];
991+ char * inhname = NameStr (inhattr -> attname );
992+
993+ if (strcmp (key -> name ,inhname )== 0 )
994+ {
995+ found = true;
996+ /*
997+ * If the column is inherited, we currently have
998+ * no easy way to force it to be NOT NULL.
999+ * Only way I can see to fix this would be to
1000+ * convert the inherited-column info to ColumnDef
1001+ * nodes before we reach this point, and then
1002+ * create the table from those nodes rather than
1003+ * referencing the parent tables later. That
1004+ * would likely be cleaner, but too much work
1005+ * to contemplate right now. Instead, raise an
1006+ * error if the inherited column won't be NOT NULL.
1007+ * (Would a NOTICE be more reasonable?)
1008+ */
1009+ if (!inhattr -> attnotnull )
1010+ elog (ERROR ,"inherited attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL" ,
1011+ inhname );
9791012break ;
9801013}
9811014}
@@ -984,24 +1017,20 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
9841017break ;
9851018}
9861019}
987- else {
988- found = 1 ;
989- }
9901020
9911021if (!found )
992- elog (ERROR ,"CREATE TABLE: column'%s' named in key does not exist" ,
1022+ elog (ERROR ,"CREATE TABLE: column\"%s\" named in key does not exist" ,
9931023key -> name );
9941024
995- if (constraint -> contype == CONSTR_PRIMARY )
996- column -> is_not_null = TRUE;
9971025iparam = makeNode (IndexElem );
9981026iparam -> name = pstrdup (key -> name );
9991027iparam -> args = NIL ;
10001028iparam -> class = NULL ;
10011029index -> indexParams = lappend (index -> indexParams ,iparam );
10021030
10031031if (index -> idxname == NULL )
1004- index -> idxname = CreateIndexName (stmt -> relname ,iparam -> name ,"key" ,ilist );
1032+ index -> idxname = CreateIndexName (stmt -> relname ,iparam -> name ,
1033+ "key" ,ilist );
10051034}
10061035
10071036if (index -> idxname == NULL )/* should not happen */