Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane1999-10-03 23:55:40 +0000
committerTom Lane1999-10-03 23:55:40 +0000
commiteabc714a916b772650c97b065ef27767dc5942e4 (patch)
tree9271817f0a846e303ae8d32338b1d58a5c2754d5 /src/backend/parser
parentf29ccc827006d13be0f4bf0255b06f3c4e921709 (diff)
Reimplement parsing and storage of default expressions and constraint
expressions in CREATE TABLE. There is no longer an emasculated expression syntax for these things; it's full a_expr for constraints, and b_expr for defaults (unfortunately the fact that NOT NULL is a part of the column constraint syntax causes a shift/reduce conflict if you try a_expr. Oh well --- at least parenthesized boolean expressions work now). Also, stored expression for a column default is not pre-coerced to the column type; we rely on transformInsertStatement to do that when the default is actually used. This means "f1 datetime default 'now'" behaves the way people usually expect it to. BTW, all the support code is now there to implement ALTER TABLE ADD CONSTRAINT and ALTER TABLE ADD COLUMN with a default value. I didn't actually teach ALTER TABLE to call it, but it wouldn't be much work.
Diffstat (limited to 'src/backend/parser')
-rw-r--r--src/backend/parser/analyze.c157
-rw-r--r--src/backend/parser/gram.y402
2 files changed, 117 insertions, 442 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 276d28b3aa1..4bcf79a7277 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: analyze.c,v 1.119 1999/09/18 19:07:12 tgl Exp $
+ * $Id: analyze.c,v 1.120 1999/10/03 23:55:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -396,7 +396,7 @@ transformInsertStmt(ParseState *pstate, InsertStmt *stmt)
if (namestrcmp(&(thisatt->attname), resnode->resname) == 0)
break;
}
- if (tl != NIL) /* something given for this attr */
+ if (tl != NIL) /* found TLE for this attr */
continue;
/*
* No user-supplied value, so add a targetentry with DEFAULT expr
@@ -573,7 +573,6 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
q = makeNode(Query);
q->commandType = CMD_UTILITY;
- elements = stmt->tableElts;
constraints = stmt->constraints;
columns = NIL;
dlist = NIL;
@@ -581,7 +580,7 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
/*
* Run through each primary element in the table creation clause
*/
- while (elements != NIL)
+ foreach(elements, stmt->tableElts)
{
element = lfirst(elements);
switch (nodeTag(element))
@@ -594,19 +593,31 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
if (column->is_sequence)
{
char *sname;
- char *cstring;
+ char *qstring;
+ A_Const *snamenode;
+ FuncCall *funccallnode;
CreateSeqStmt *sequence;
sname = makeObjectName(stmt->relname, column->colname,
"seq");
+ /*
+ * Create an expression tree representing the function
+ * call nextval('"sequencename"')
+ */
+ qstring = palloc(strlen(sname) + 2 + 1);
+ sprintf(qstring, "\"%s\"", sname);
+ snamenode = makeNode(A_Const);
+ snamenode->val.type = T_String;
+ snamenode->val.val.str = qstring;
+ funccallnode = makeNode(FuncCall);
+ funccallnode->funcname = "nextval";
+ funccallnode->args = lcons(snamenode, NIL);
+
constraint = makeNode(Constraint);
constraint->contype = CONSTR_DEFAULT;
constraint->name = sname;
- cstring = palloc(10 + strlen(constraint->name) + 3 + 1);
- strcpy(cstring, "nextval('\"");
- strcat(cstring, constraint->name);
- strcat(cstring, "\"')");
- constraint->def = cstring;
+ constraint->raw_expr = (Node *) funccallnode;
+ constraint->cooked_expr = NULL;
constraint->keys = NULL;
column->constraints = lappend(column->constraints, constraint);
@@ -628,69 +639,65 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
blist = lcons(sequence, NIL);
}
- /* Check for column constraints, if any... */
- if (column->constraints != NIL)
+ /* Process column constraints, if any... */
+ foreach(clist, column->constraints)
{
- clist = column->constraints;
- while (clist != NIL)
+ constraint = lfirst(clist);
+ switch (constraint->contype)
{
- constraint = lfirst(clist);
- switch (constraint->contype)
- {
- case CONSTR_NULL:
-
- /*
- * We should mark this explicitly, so we
- * can tell if NULL and NOT NULL are both
- * specified
- */
- if (column->is_not_null)
- elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
- " for '%s.%s'", stmt->relname, column->colname);
- column->is_not_null = FALSE;
- break;
-
- case CONSTR_NOTNULL:
- if (column->is_not_null)
- elog(ERROR, "CREATE TABLE/NOT NULL already specified"
- " for '%s.%s'", stmt->relname, column->colname);
- column->is_not_null = TRUE;
- break;
-
- case CONSTR_DEFAULT:
- if (column->defval != NULL)
- elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
- " for '%s.%s'", stmt->relname, column->colname);
- column->defval = constraint->def;
- break;
-
- case CONSTR_PRIMARY:
- if (constraint->name == NULL)
- constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
- if (constraint->keys == NIL)
- constraint->keys = lappend(constraint->keys, column);
- dlist = lappend(dlist, constraint);
- break;
-
- case CONSTR_UNIQUE:
- if (constraint->name == NULL)
- constraint->name = makeObjectName(stmt->relname, column->colname, "key");
- if (constraint->keys == NIL)
- constraint->keys = lappend(constraint->keys, column);
- dlist = lappend(dlist, constraint);
- break;
-
- case CONSTR_CHECK:
- constraints = lappend(constraints, constraint);
- if (constraint->name == NULL)
- constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
- break;
-
- default:
- elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
- break;
- }
- clist = lnext(clist);
+ case CONSTR_NULL:
+
+ /*
+ * We should mark this explicitly, so we
+ * can tell if NULL and NOT NULL are both
+ * specified
+ */
+ if (column->is_not_null)
+ elog(ERROR, "CREATE TABLE/(NOT) NULL conflicting declaration"
+ " for '%s.%s'", stmt->relname, column->colname);
+ column->is_not_null = FALSE;
+ break;
+
+ case CONSTR_NOTNULL:
+ if (column->is_not_null)
+ elog(ERROR, "CREATE TABLE/NOT NULL already specified"
+ " for '%s.%s'", stmt->relname, column->colname);
+ column->is_not_null = TRUE;
+ break;
+
+ case CONSTR_DEFAULT:
+ if (column->raw_default != NULL)
+ elog(ERROR, "CREATE TABLE/DEFAULT multiple values specified"
+ " for '%s.%s'", stmt->relname, column->colname);
+ column->raw_default = constraint->raw_expr;
+ Assert(constraint->cooked_expr == NULL);
+ break;
+
+ case CONSTR_PRIMARY:
+ if (constraint->name == NULL)
+ constraint->name = makeObjectName(stmt->relname, NULL, "pkey");
+ if (constraint->keys == NIL)
+ constraint->keys = lappend(constraint->keys, column);
+ dlist = lappend(dlist, constraint);
+ break;
+
+ case CONSTR_UNIQUE:
+ if (constraint->name == NULL)
+ constraint->name = makeObjectName(stmt->relname, column->colname, "key");
+ if (constraint->keys == NIL)
+ constraint->keys = lappend(constraint->keys, column);
+ dlist = lappend(dlist, constraint);
+ break;
+
+ case CONSTR_CHECK:
+ if (constraint->name == NULL)
+ constraint->name = makeObjectName(stmt->relname, column->colname, NULL);
+ constraints = lappend(constraints, constraint);
+ break;
+
+ default:
+ elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
+ break;
}
}
break;
@@ -715,19 +722,17 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
case CONSTR_NOTNULL:
case CONSTR_DEFAULT:
- elog(ERROR, "parser: illegal context for constraint (internal error)", NULL);
+ elog(ERROR, "parser: illegal context for constraint (internal error)");
break;
default:
- elog(ERROR, "parser: unrecognized constraint (internal error)", NULL);
+ elog(ERROR, "parser: unrecognized constraint (internal error)");
break;
}
break;
default:
- elog(ERROR, "parser: unrecognized node (internal error)", NULL);
+ elog(ERROR, "parser: unrecognized node (internal error)");
}
-
- elements = lnext(elements);
}
stmt->tableElts = columns;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 96f480ea0ca..87c82839df4 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.105 1999/10/02 21:33:21 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.106 1999/10/03 23:55:30 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -72,8 +72,6 @@ static char *xlateSqlType(char *);
static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
static Node *makeRowExpr(char *opr, List *largs, List *rargs);
static void mapTargetColumns(List *source, List *target);
-static List *makeConstantList( A_Const *node);
-static char *FlattenStringList(List *list);
static char *fmtId(char *rawid);
static void param_type_init(Oid *typev, int nargs);
static Node *doNegate(Node *n);
@@ -217,7 +215,7 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <node> def_arg, columnElem, where_clause,
a_expr, a_expr_or_null, b_expr, AexprConst,
in_expr, having_clause
-%type <list> row_descriptor, row_list, c_list, c_expr, in_expr_nodes
+%type <list> row_descriptor, row_list, in_expr_nodes
%type <node> row_expr
%type <str> row_op
%type <node> case_expr, case_arg, when_clause, case_default
@@ -250,8 +248,6 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <str> TypeId
%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
@@ -716,7 +712,7 @@ alter_clause: ADD opt_column columnDef
}
| DROP opt_column ColId
{ elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
- | ALTER opt_column ColId SET DEFAULT default_expr
+ | ALTER opt_column ColId SET DEFAULT a_expr
{ elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
| ALTER opt_column ColId DROP DEFAULT
{ elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
@@ -864,7 +860,8 @@ columnDef: ColId Typename ColQualifier
ColumnDef *n = makeNode(ColumnDef);
n->colname = $1;
n->typename = $2;
- n->defval = NULL;
+ n->raw_default = NULL;
+ n->cooked_default = NULL;
n->is_not_null = FALSE;
n->constraints = $3;
$$ = (Node *)n;
@@ -875,7 +872,8 @@ columnDef: ColId Typename ColQualifier
n->colname = $1;
n->typename = makeNode(TypeName);
n->typename->name = xlateSqlType("integer");
- n->defval = NULL;
+ n->raw_default = NULL;
+ n->cooked_default = NULL;
n->is_not_null = TRUE;
n->is_sequence = TRUE;
n->constraints = $3;
@@ -909,7 +907,8 @@ ColPrimaryKey: PRIMARY KEY
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = lcons((Node *)n, NIL);
}
@@ -928,7 +927,7 @@ ColConstraint:
;
/* DEFAULT NULL is already the default for Postgres.
- * Bue define it here and carry it forward into the system
+ * But define it here and carry it forward into the system
* to make it explicit.
* - thomas 1998-09-13
* WITH NULL and NULL are not SQL92-standard syntax elements,
@@ -936,13 +935,17 @@ ColConstraint:
* that a column may have that value. WITH NULL leads to
* shift/reduce conflicts with WITH TIME ZONE anyway.
* - thomas 1999-01-08
+ * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
+ * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
+ * or be part of a_expr NOT LIKE or similar constructs).
*/
-ColConstraintElem: CHECK '(' constraint_expr ')'
+ColConstraintElem: CHECK '(' a_expr ')'
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_CHECK;
n->name = NULL;
- n->def = FlattenStringList($3);
+ n->raw_expr = $3;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = (Node *)n;
}
@@ -951,16 +954,18 @@ ColConstraintElem: CHECK '(' constraint_expr ')'
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_DEFAULT;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = (Node *)n;
}
- | DEFAULT default_expr
+ | DEFAULT b_expr
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_DEFAULT;
n->name = NULL;
- n->def = FlattenStringList($2);
+ n->raw_expr = $2;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = (Node *)n;
}
@@ -969,7 +974,8 @@ ColConstraintElem: CHECK '(' constraint_expr ')'
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_NOTNULL;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = (Node *)n;
}
@@ -978,7 +984,8 @@ ColConstraintElem: CHECK '(' constraint_expr ')'
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = (Node *)n;
}
@@ -987,7 +994,8 @@ ColConstraintElem: CHECK '(' constraint_expr ')'
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = NULL;
$$ = (Node *)n;
}
@@ -998,112 +1006,6 @@ ColConstraintElem: CHECK '(' constraint_expr ')'
}
;
-default_list: default_list ',' default_expr
- {
- $$ = lappend($1,makeString(","));
- $$ = nconc($$, $3);
- }
- | default_expr
- {
- $$ = $1;
- }
- ;
-
-/* 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
- { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
- | default_expr '-' default_expr
- { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
- | default_expr '/' default_expr
- { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
- | default_expr '%' default_expr
- { $$ = nconc( $1, lcons( makeString( "%"), $3)); }
- | default_expr '*' default_expr
- { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
- | default_expr '^' default_expr
- { $$ = nconc( $1, lcons( makeString( "^"), $3)); }
- | default_expr '|' default_expr
- { $$ = nconc( $1, lcons( makeString( "|"), $3)); }
- | default_expr '=' default_expr
- { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
- | default_expr '<' default_expr
- { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
- | default_expr '>' default_expr
- { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
- | ':' default_expr
- { $$ = lcons( makeString( ":"), $2); }
- | ';' default_expr
- { $$ = lcons( makeString( ";"), $2); }
- | '|' default_expr
- { $$ = lcons( makeString( "|"), $2); }
- | default_expr TYPECAST Typename
- {
- $3->name = fmtId($3->name);
- $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
- }
- | CAST '(' default_expr AS Typename ')'
- {
- $5->name = fmtId($5->name);
- $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
- }
- | '(' default_expr ')'
- { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
- | func_name '(' ')'
- {
- $$ = makeList( makeString($1), makeString("("), -1);
- $$ = lappend( $$, makeString(")"));
- }
- | func_name '(' default_list ')'
- {
- $$ = makeList( makeString($1), makeString("("), -1);
- $$ = nconc( $$, $3);
- $$ = lappend( $$, makeString(")"));
- }
- | default_expr Op default_expr
- {
- if (!strcmp("<=", $2) || !strcmp(">=", $2))
- elog(ERROR,"boolean expressions not supported in DEFAULT");
- $$ = nconc( $1, lcons( makeString( $2), $3));
- }
- | Op default_expr
- { $$ = lcons( makeString( $1), $2); }
- | default_expr Op
- { $$ = lappend( $1, makeString( $2)); }
- /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
- | CURRENT_DATE
- { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
- | CURRENT_TIME
- { $$ = lcons( makeString( "'now'::time"), NIL); }
- | CURRENT_TIME '(' Iconst ')'
- {
- if ($3 != 0)
- elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
- $$ = lcons( makeString( "'now'::time"), NIL);
- }
- | CURRENT_TIMESTAMP
- { $$ = lcons( makeString( "now()"), NIL); }
- | CURRENT_TIMESTAMP '(' Iconst ')'
- {
- if ($3 != 0)
- elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
- $$ = lcons( makeString( "now()"), NIL);
- }
- | CURRENT_USER
- { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
- | USER
- { $$ = lcons( makeString( "USER"), NIL); }
- ;
-
/* ConstraintElem specifies constraint syntax which is not embedded into
* a column definition. ColConstraintElem specifies the embedded form.
* - thomas 1997-12-03
@@ -1118,12 +1020,13 @@ TableConstraint: CONSTRAINT name ConstraintElem
{ $$ = $1; }
;
-ConstraintElem: CHECK '(' constraint_expr ')'
+ConstraintElem: CHECK '(' a_expr ')'
{
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_CHECK;
n->name = NULL;
- n->def = FlattenStringList($3);
+ n->raw_expr = $3;
+ n->cooked_expr = NULL;
$$ = (Node *)n;
}
| UNIQUE '(' columnList ')'
@@ -1131,7 +1034,8 @@ ConstraintElem: CHECK '(' constraint_expr ')'
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_UNIQUE;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = $3;
$$ = (Node *)n;
}
@@ -1140,7 +1044,8 @@ ConstraintElem: CHECK '(' constraint_expr ')'
Constraint *n = makeNode(Constraint);
n->contype = CONSTR_PRIMARY;
n->name = NULL;
- n->def = NULL;
+ n->raw_expr = NULL;
+ n->cooked_expr = NULL;
n->keys = $4;
$$ = (Node *)n;
}
@@ -1151,153 +1056,6 @@ ConstraintElem: CHECK '(' constraint_expr ')'
}
;
-constraint_list: constraint_list ',' constraint_expr
- {
- $$ = lappend($1,makeString(","));
- $$ = nconc($$, $3);
- }
- | constraint_expr
- {
- $$ = $1;
- }
- ;
-
-constraint_expr: AexprConst
- { $$ = makeConstantList((A_Const *) $1); }
- | NULL_P
- { $$ = lcons( makeString("NULL"), NIL); }
- | ColId
- {
- $$ = lcons( makeString(fmtId($1)), NIL);
- }
- | '-' constraint_expr %prec UMINUS
- { $$ = lcons( makeString( "-"), $2); }
- | constraint_expr '+' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
- | constraint_expr '-' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
- | constraint_expr '/' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
- | constraint_expr '%' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "%"), $3)); }
- | constraint_expr '*' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
- | constraint_expr '^' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "^"), $3)); }
- | constraint_expr '|' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "|"), $3)); }
- | constraint_expr '=' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "="), $3)); }
- | constraint_expr '<' constraint_expr
- { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
- | constraint_expr '>' constraint_expr
- { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
- | ':' constraint_expr
- { $$ = lcons( makeString( ":"), $2); }
- | ';' constraint_expr
- { $$ = lcons( makeString( ";"), $2); }
- | '|' constraint_expr
- { $$ = lcons( makeString( "|"), $2); }
- | constraint_expr TYPECAST Typename
- {
- $3->name = fmtId($3->name);
- $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
- }
- | CAST '(' constraint_expr AS Typename ')'
- {
- $5->name = fmtId($5->name);
- $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
- }
- | '(' constraint_expr ')'
- { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
- | func_name '(' ')'
- {
- $$ = makeList( makeString($1), makeString("("), -1);
- $$ = lappend( $$, makeString(")"));
- }
- | func_name '(' constraint_list ')'
- {
- $$ = makeList( makeString($1), makeString("("), -1);
- $$ = nconc( $$, $3);
- $$ = lappend( $$, makeString(")"));
- }
- | constraint_expr Op constraint_expr
- { $$ = nconc( $1, lcons( makeString( $2), $3)); }
- | constraint_expr LIKE constraint_expr
- { $$ = nconc( $1, lcons( makeString( "LIKE"), $3)); }
- | constraint_expr NOT LIKE constraint_expr
- { $$ = nconc( $1, lcons( makeString( "NOT LIKE"), $4)); }
- | constraint_expr AND constraint_expr
- { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
- | constraint_expr OR constraint_expr
- { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
- | NOT constraint_expr
- { $$ = lcons( makeString( "NOT"), $2); }
- | Op constraint_expr
- { $$ = lcons( makeString( $1), $2); }
- | constraint_expr Op
- { $$ = lappend( $1, makeString( $2)); }
- | constraint_expr ISNULL
- { $$ = lappend( $1, makeString( "IS NULL")); }
- | constraint_expr IS NULL_P
- { $$ = lappend( $1, makeString( "IS NULL")); }
- | constraint_expr NOTNULL
- { $$ = lappend( $1, makeString( "IS NOT NULL")); }
- | constraint_expr IS NOT NULL_P
- { $$ = lappend( $1, makeString( "IS NOT NULL")); }
- | constraint_expr IS TRUE_P
- { $$ = lappend( $1, makeString( "IS TRUE")); }
- | constraint_expr IS FALSE_P
- { $$ = lappend( $1, makeString( "IS FALSE")); }
- | constraint_expr IS NOT TRUE_P
- { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
- | constraint_expr IS NOT FALSE_P
- { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
- | constraint_expr IN '(' c_list ')'
- {
- $$ = lappend( $1, makeString("IN"));
- $$ = lappend( $$, makeString("("));
- $$ = nconc( $$, $4);
- $$ = lappend( $$, makeString(")"));
- }
- | constraint_expr NOT IN '(' c_list ')'
- {
- $$ = lappend( $1, makeString("NOT IN"));
- $$ = lappend( $$, makeString("("));
- $$ = nconc( $$, $5);
- $$ = lappend( $$, makeString(")"));
- }
- | constraint_expr BETWEEN c_expr AND c_expr
- {
- $$ = lappend( $1, makeString("BETWEEN"));
- $$ = nconc( $$, $3);
- $$ = lappend( $$, makeString("AND"));
- $$ = nconc( $$, $5);
- }
- | constraint_expr NOT BETWEEN c_expr AND c_expr
- {
- $$ = lappend( $1, makeString("NOT BETWEEN"));
- $$ = nconc( $$, $4);
- $$ = lappend( $$, makeString("AND"));
- $$ = nconc( $$, $6);
- }
- ;
-
-c_list: c_list ',' c_expr
- {
- $$ = lappend($1, makeString(","));
- $$ = nconc($$, $3);
- }
- | c_expr
- {
- $$ = $1;
- }
- ;
-
-c_expr: AexprConst
- { $$ = makeConstantList((A_Const *) $1); }
- ;
-
key_match: MATCH FULL { $$ = NULL; }
| MATCH PARTIAL { $$ = NULL; }
| /*EMPTY*/ { $$ = NULL; }
@@ -1346,7 +1104,8 @@ CreateAsElement: ColId
ColumnDef *n = makeNode(ColumnDef);
n->colname = $1;
n->typename = NULL;
- n->defval = NULL;
+ n->raw_default = NULL;
+ n->cooked_default = NULL;
n->is_not_null = FALSE;
n->constraints = NULL;
$$ = (Node *)n;
@@ -5495,95 +5254,6 @@ void parser_init(Oid *typev, int nargs)
}
-/* FlattenStringList()
- * Traverse list of string nodes and convert to a single string.
- * Used for reconstructing string form of complex expressions.
- *
- * Allocate at least one byte for terminator.
- */
-static char *
-FlattenStringList(List *list)
-{
- List *l;
- Value *v;
- char *s;
- char *sp;
- int nlist, len = 0;
-
- nlist = length(list);
- l = list;
- while(l != NIL) {
- v = (Value *)lfirst(l);
- sp = v->val.str;
- l = lnext(l);
- len += strlen(sp);
- };
- len += nlist;
-
- s = (char*) palloc(len+1);
- *s = '\0';
-
- l = list;
- while(l != NIL) {
- v = (Value *)lfirst(l);
- sp = v->val.str;
- l = lnext(l);
- strcat(s,sp);
- if (l != NIL) strcat(s," ");
- };
- *(s+len) = '\0';
-
- return s;
-} /* FlattenStringList() */
-
-
-/* makeConstantList()
- * Convert constant value node into string node.
- */
-static List *
-makeConstantList( A_Const *n)
-{
- List *result = NIL;
- char *typval = NULL;
- char *defval = NULL;
-
- if (nodeTag(n) != T_A_Const) {
- elog(ERROR,"Cannot handle non-constant parameter");
-
- } else if (n->val.type == T_Float) {
- defval = (char*) palloc(20+1);
- sprintf( defval, "%g", n->val.val.dval);
- result = lcons( makeString(defval), NIL);
-
- } else if (n->val.type == T_Integer) {
- defval = (char*) palloc(20+1);
- sprintf( defval, "%ld", n->val.val.ival);
- result = lcons( makeString(defval), NIL);
-
- } else if (n->val.type == T_String) {
- defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
- strcpy( defval, "'");
- strcat( defval, ((A_Const *) n)->val.val.str);
- strcat( defval, "'");
- if (n->typename != NULL)
- {
- typval = (char*) palloc(strlen( n->typename->name) + 1);
- strcpy(typval, n->typename->name);
- result = lappend( lcons( makeString(typval), NIL), makeString(defval));
- }
- else
- {
- result = lcons( makeString(defval), NIL);
- }
-
- } else {
- elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
- };
-
- return result;
-} /* makeConstantList() */
-
-
/* fmtId()
* Check input string for non-lowercase/non-numeric characters.
* Returns either input string or input surrounded by double quotes.