Serial syntax, DEFAULT NULL, and rules - Mailing list pgsql-hackers
From | Thomas G. Lockhart |
---|---|
Subject | Serial syntax, DEFAULT NULL, and rules |
Date | |
Msg-id | 35FFD59D.FF6ADC81@alumni.caltech.edu Whole thread Raw |
In response to | Serial syntax (darcy@druid.net (D'Arcy J.M. Cain)) |
List | pgsql-hackers |
> > Yeah. I'm testing some patches now... I've committed patches to the cvs source tree to allow PRIMARY KEY to be specified with the SERIAL type. The patches also fix some DEFAULT NULL problems and the "SELECT @1" problem. With these patches and fixes for the rules regression tests and results all regression tests pass on my linux-2.0.30/i686 machine. I've enclosed the source patches _except_ for the regression test changes, since those involve new files, etc. Also, I have _not_ updated gram.c yet, so anyone building in the next few days may need bison to build. If that is a problem someone can go ahead and build and commit a new gram.c. I'm out of town tomorrow through Sunday, but keep those cards and letters coming :) - Tom *** ../src/backend/parser/analyze.c.orig Thu Sep 3 14:21:06 1998 --- ../src/backend/parser/analyze.c Wed Sep 16 04:41:24 1998 *************** *** 530,540 **** --- 530,555 ---- constraint->def = cstring; constraint->keys = NULL; + /* The parser only allows PRIMARY KEY as a constraint for the SERIAL type. + * So, if there is a constraint of any kind, assume it is that. + * If PRIMARY KEY is specified, then don't need to gin up a UNIQUE constraint + * since that will be covered already. + * - thomas 1998-09-15 + */ if (column->constraints != NIL) + { column->constraints = lappend(column->constraints, constraint); + } else + { column->constraints = lcons(constraint, NIL); + constraint = makeNode(Constraint); + constraint->contype = CONSTR_UNIQUE; + constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL); + column->constraints = lappend(column->constraints, constraint); + } + sequence = makeNode(CreateSeqStmt); sequence->seqname = pstrdup(constraint->name); sequence->options = NIL; *************** *** 543,554 **** sequence->seqname, stmt->relname, column->colname); ilist = lcons(sequence, NIL); - - constraint = makeNode(Constraint); - constraint->contype = CONSTR_UNIQUE; - constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL); - - column->constraints = lappend(column->constraints, constraint); } if (column->constraints != NIL) --- 558,563 ---- *** ../src/backend/parser/gram.y.orig Sun Sep 13 04:35:12 1998 --- ../src/backend/parser/gram.y Wed Sep 16 04:43:47 1998 *************** *** 236,242 **** %type <node> TableConstraint %type <list> constraint_list, constraint_expr %type <list> default_list, default_expr ! %type <list> ColQualList, ColQualifier %type <node> ColConstraint, ColConstraintElem %type <list> key_actions, key_action %type <str> key_match, key_reference --- 236,242 ---- %type <node> TableConstraint %type <list> constraint_list, constraint_expr %type <list> default_list, default_expr ! %type <list> ColPrimaryKey, ColQualList, ColQualifier %type <node> ColConstraint, ColConstraintElem %type <list> key_actions, key_action %type <str> key_match, key_reference *************** *** 751,757 **** n->constraints = $3; $$ = (Node *)n; } ! | ColId SERIAL { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; --- 751,757 ---- n->constraints = $3; $$ = (Node *)n; } ! | ColId SERIAL ColPrimaryKey { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; *************** *** 760,766 **** n->defval = NULL; n->is_not_null = TRUE; n->is_sequence = TRUE; ! n->constraints = NULL; $$ = (Node *)n; } --- 760,766 ---- n->defval = NULL; n->is_not_null = TRUE; n->is_sequence = TRUE; ! n->constraints = $3; $$ = (Node *)n; } *************** *** 786,791 **** --- 786,803 ---- } ; + ColPrimaryKey: PRIMARY KEY + { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_PRIMARY; + n->name = NULL; + n->def = NULL; + n->keys = NULL; + $$ = lcons((Node *)n, NIL); + } + | /*EMPTY*/ { $$ = NULL; } + ; + ColConstraint: CONSTRAINT name ColConstraintElem { *************** *** 806,811 **** --- 818,828 ---- $$ = NULL; } * - thomas 1998-09-12 + * + * DEFAULT NULL is already the default for Postgres. + * Bue define it here and carry it forward into the system + * to make it explicit. + * - thomas 1998-09-13 */ ColConstraintElem: CHECK '(' constraint_expr ')' { *************** *** 816,821 **** --- 833,847 ---- n->keys = NULL; $$ = (Node *)n; } + | DEFAULT NULL_P + { + Constraint *n = makeNode(Constraint); + n->contype = CONSTR_DEFAULT; + n->name = NULL; + n->def = NULL; + n->keys = NULL; + $$ = (Node *)n; + } | DEFAULT default_expr { Constraint *n = makeNode(Constraint); *************** *** 870,879 **** } ; ! default_expr: AexprConst ! { $$ = makeConstantList((A_Const *) $1); } | NULL_P { $$ = lcons( makeString("NULL"), NIL); } | '-' default_expr %prec UMINUS { $$ = lcons( makeString( "-"), $2); } | default_expr '+' default_expr --- 896,910 ---- } ; ! /* The Postgres default column value is NULL. ! * Rather than carrying DEFAULT NULL forward as a clause, ! * let's just have it be a no-op. | NULL_P { $$ = lcons( makeString("NULL"), NIL); } + * - thomas 1998-09-13 + */ + default_expr: AexprConst + { $$ = makeConstantList((A_Const *) $1); } | '-' default_expr %prec UMINUS { $$ = lcons( makeString( "-"), $2); } | default_expr '+' default_expr *** ../src/backend/parser/parse_oper.c.orig Tue Sep 1 04:30:34 1998 --- ../src/backend/parser/parse_oper.c Wed Sep 16 06:23:39 1998 *************** *** 312,318 **** if (ncandidates <= 1) { if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ! || !can_coerce_type(1, &input_typeids[1], &candidates->args[1])) { ncandidates = 0; #ifdef PARSEDEBUG --- 312,318 ---- if (ncandidates <= 1) { if (!can_coerce_type(1, &input_typeids[0], &candidates->args[0]) ! || ((nargs > 1) && !can_coerce_type(1, &input_typeids[1], &candidates->args[1]))) { ncandidates = 0; #ifdef PARSEDEBUG *************** *** 718,724 **** } else { ! targetOid = func_select_candidate(1, &arg, candidates); if (targetOid != NULL) { --- 718,724 ---- } else { ! targetOid = oper_select_candidate(1, &arg, candidates); if (targetOid != NULL) { *************** *** 729,740 **** CharGetDatum('r')); } else tup = NULL; if (!HeapTupleIsValid(tup)) { ! elog(ERROR, "Unable to convert right operator '%s' from type %s to %s", ! op, typeidTypeName(arg), typeidTypeName(*targetOid)); return NULL; } } --- 729,742 ---- CharGetDatum('r')); } else + { tup = NULL; + } if (!HeapTupleIsValid(tup)) { ! elog(ERROR, "Unable to convert right operator '%s' from type %s", ! op, typeidTypeName(arg)); return NULL; } } *************** *** 782,798 **** } else { ! targetOid = func_select_candidate(1, &arg, candidates); ! tup = SearchSysCacheTuple(OPRNAME, ! PointerGetDatum(op), ! ObjectIdGetDatum(InvalidOid), ! ObjectIdGetDatum(*targetOid), ! CharGetDatum('l')); if (!HeapTupleIsValid(tup)) { ! elog(ERROR, "Unable to convert left operator '%s' from type %s to %s", ! op, typeidTypeName(arg), typeidTypeName(*targetOid)); return NULL; } #ifdef PARSEDEBUG --- 784,807 ---- } else { ! targetOid = oper_select_candidate(1, &arg, candidates); ! if (targetOid != NULL) ! { ! tup = SearchSysCacheTuple(OPRNAME, ! PointerGetDatum(op), ! ObjectIdGetDatum(InvalidOid), ! ObjectIdGetDatum(*targetOid), ! CharGetDatum('l')); ! } ! else ! { ! tup = NULL; ! } if (!HeapTupleIsValid(tup)) { ! elog(ERROR, "Unable to convert left operator '%s' from type %s", ! op, typeidTypeName(arg)); return NULL; } #ifdef PARSEDEBUG
pgsql-hackers by date: