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:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] 6.4-BETA1: libpgtcl.so / Tcl version?
Next
From: Brook Milligan
Date:
Subject: geometry-NetBSD.out patch