*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.51 1997/11/26 01:11:03 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.52 1997/12/04 23:07:18 thomas Exp $
*
*-------------------------------------------------------------------------
*/
#include
#include
+#include
#include
#include "postgres.h"
static Query *transformSelectStmt(ParseState *pstate, RetrieveStmt *stmt);
static Query *transformUpdateStmt(ParseState *pstate, ReplaceStmt *stmt);
static Query *transformCursorStmt(ParseState *pstate, CursorStmt *stmt);
+static Query *transformCreateStmt(ParseState *pstate, CreateStmt *stmt);
+List *extras = NIL;
/*
* parse_analyze -
{
pstate = make_parsestate();
result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
+ if (extras != NIL)
+ {
+ result->len += length(extras);
+ result->qtrees = (Query **) realloc(result->qtrees, result->len * sizeof(Query *));
+ while (extras != NIL)
+ {
+ result->qtrees[i++] = transformStmt(pstate, lfirst(extras));
+ extras = lnext(extras);
+ }
+ }
+ extras = NIL;
pl = lnext(pl);
if (pstate->p_target_relation != NULL)
heap_close(pstate->p_target_relation);
* Non-optimizable statements
*------------------------
*/
+ case T_CreateStmt:
+ result = transformCreateStmt(pstate, (CreateStmt *) parseTree);
+ break;
+
case T_IndexStmt:
result = transformIndexStmt(pstate, (IndexStmt *) parseTree);
break;
return (Query *) qry;
}
+/* makeTableName()
+ * Create a table name from a list of fields.
+ */
+static char *
+makeTableName(void *elem,...);
+
+static char *
+makeTableName(void *elem,...)
+{
+ va_list args;
+
+ char *name;
+ char buf[NAMEDATALEN+1];
+
+ strcpy(buf,"");
+
+ va_start(args,elem);
+
+ name = elem;
+ while (name != NULL)
+ {
+ /* not enough room for next part? then return nothing */
+ if ((strlen(buf)+strlen(name)) >= (sizeof(buf)-1))
+ return (NULL);
+
+ if (strlen(buf) > 0) strcat(buf,"_");
+ strcat(buf,name);
+
+ name = va_arg(args,void *);
+ }
+
+ va_end(args);
+
+ name = palloc(strlen(buf)+1);
+ strcpy(name,buf);
+
+ return (name);
+} /* makeTableName() */
+
+/*
+ * transformCreateStmt -
+ * transforms the "create table" statement
+ * SQL92 allows constraints to be scattered all over, so thumb through
+ * the columns and collect all constraints into one place.
+ * If there are any implied indices (e.g. UNIQUE or PRIMARY KEY)
+ * then expand those into multiple IndexStmt blocks.
+ * - thomas 1997-12-02
+ */
+static Query *
+transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
+{
+ Query *q;
+ List *elements;
+ Node *element;
+ List *columns;
+ List *dlist;
+ ColumnDef *column;
+ List *constraints, *clist;
+ Constraint *constraint;
+ List *keys;
+ Ident *key;
+ List *ilist;
+ IndexStmt *index;
+ IndexElem *iparam;
+
+ q = makeNode(Query);
+ q->commandType = CMD_UTILITY;
+
+ elements = stmt->tableElts;
+ constraints = stmt->constraints;
+ columns = NIL;
+ dlist = NIL;
+
+ while (elements != NIL)
+ {
+ element = lfirst(elements);
+ switch (nodeTag(element))
+ {
+ case T_ColumnDef:
+ column = (ColumnDef *) element;
+#if PARSEDEBUG
+printf("transformCreateStmt- found column %s\n",column->colname);
+#endif
+ columns = lappend(columns,column);
+ if (column->constraints != NIL)
+ {
+#if PARSEDEBUG
+printf("transformCreateStmt- found constraint(s) on column %s\n",column->colname);
+#endif
+ clist = column->constraints;
+ while (clist != NIL)
+ {
+ constraint = lfirst(clist);
+ switch (constraint->contype)
+ {
+ case CONSTR_NOTNULL:
+#if PARSEDEBUG
+printf("transformCreateStmt- found NOT NULL constraint on column %s\n",column->colname);
+#endif
+ if (column->is_not_null)
+ elog(WARN,"CREATE TABLE/NOT NULL already specified"
+ " for %s.%s", stmt->relname, column->colname);
+ column->is_not_null = TRUE;
+ break;
+
+ case CONSTR_DEFAULT:
+#if PARSEDEBUG
+printf("transformCreateStmt- found DEFAULT clause on column %s\n",column->colname);
+#endif
+ if (column->defval != NULL)
+ elog(WARN,"CREATE TABLE/DEFAULT multiple values specified"
+ " for %s.%s", stmt->relname, column->colname);
+ column->defval = constraint->def;
+ break;
+
+ case CONSTR_PRIMARY:
+#if PARSEDEBUG
+printf("transformCreateStmt- found PRIMARY KEY clause on column %s\n",column->colname);
+#endif
+ if (constraint->name == NULL)
+ constraint->name = makeTableName(stmt->relname, "pkey", NULL);
+ if (constraint->keys == NIL)
+ constraint->keys = lappend(constraint->keys, column);
+ dlist = lappend(dlist, constraint);
+ break;
+
+ case CONSTR_UNIQUE:
+#if PARSEDEBUG
+printf("transformCreateStmt- found UNIQUE clause on column %s\n",column->colname);
+#endif
+ if (constraint->name == NULL)
+ constraint->name = makeTableName(stmt->relname, column->colname, "key", NULL);
+ if (constraint->keys == NIL)
+ constraint->keys = lappend(constraint->keys, column);
+ dlist = lappend(dlist, constraint);
+ break;
+
+ case CONSTR_CHECK:
+#if PARSEDEBUG
+printf("transformCreateStmt- found CHECK clause on column %s\n",column->colname);
+#endif
+ constraints = lappend(constraints, constraint);
+ if (constraint->name == NULL)
+ constraint->name = makeTableName(stmt->relname, ".", column->colname, NULL);
+ break;
+
+ default:
+ elog(WARN,"parser: internal error; unrecognized constraint",NULL);
+ break;
+ }
+ clist = lnext(clist);
+ }
+ }
+ break;
+
+ case T_Constraint:
+ constraint = (Constraint *) element;
+#if PARSEDEBUG
+printf("transformCreateStmt- found constraint %s\n", ((constraint->name != NULL)? constraint->name: "(unknown)"));
+#endif
+ switch (constraint->contype)
+ {
+ case CONSTR_PRIMARY:
+#if PARSEDEBUG
+printf("transformCreateStmt- found PRIMARY KEY clause\n");
+#endif
+ if (constraint->name == NULL)
+ constraint->name = makeTableName(stmt->relname, "pkey", NULL);
+ dlist = lappend(dlist, constraint);
+ break;
+
+ case CONSTR_UNIQUE:
+#if PARSEDEBUG
+printf("transformCreateStmt- found UNIQUE clause\n");
+#endif
+#if FALSE
+ if (constraint->name == NULL)
+ constraint->name = makeTableName(stmt->relname, "key", NULL);
+#endif
+ dlist = lappend(dlist, constraint);
+ break;
+
+ case CONSTR_CHECK:
+#if PARSEDEBUG
+printf("transformCreateStmt- found CHECK clause\n");
+#endif
+ constraints = lappend(constraints, constraint);
+ break;
+
+ case CONSTR_NOTNULL:
+ case CONSTR_DEFAULT:
+ elog(WARN,"parser: internal error; illegal context for constraint",NULL);
+ break;
+ default:
+ elog(WARN,"parser: internal error; unrecognized constraint",NULL);
+ break;
+ }
+ break;
+
+ default:
+ elog(WARN,"parser: internal error; unrecognized node",NULL);
+ }
+
+ elements = lnext(elements);
+ }
+
+ stmt->tableElts = columns;
+ stmt->constraints = constraints;
+
+/* Now run through the "deferred list" to complete the query transformation.
+ * For PRIMARY KEYs, mark each column as NOT NULL and create an index.
+ * For UNIQUE, create an index as for PRIMARY KEYS, but do not insist on NOT NULL.
+ *
+ * Note that this code does not currently look for all possible redundant cases
+ * and either ignore or stop with warning. The create will fail later when
+ * names for indices turn out to be redundant, or a user might just find
+ * extra useless indices which might kill performance. - thomas 1997-12-04
+ */
+ ilist = NIL;
+ while (dlist != NIL)
+ {
+ constraint = lfirst(dlist);
+ if (nodeTag(constraint) != T_Constraint)
+ elog(WARN,"parser: internal error; unrecognized deferred node",NULL);
+
+ if ((constraint->contype != CONSTR_PRIMARY)
+ && (constraint->contype != CONSTR_UNIQUE))
+ elog(WARN,"parser: internal error; illegal deferred constraint",NULL);
+
+#if PARSEDEBUG
+printf("transformCreateStmt- found deferred constraint %s\n",
+ ((constraint->name != NULL)? constraint->name: "(unknown)"));
+#endif
+
+#if PARSEDEBUG
+printf("transformCreateStmt- found deferred %s clause\n",
+ (constraint->contype == CONSTR_PRIMARY? "PRIMARY KEY": "UNIQUE"));
+#endif
+ index = makeNode(IndexStmt);
+ ilist = lappend(ilist, index);
+
+ index->unique = TRUE;
+ if (constraint->name != NULL)
+ index->idxname = constraint->name;
+ else if (constraint->contype == CONSTR_PRIMARY)
+ index->idxname = makeTableName(stmt->relname, "pkey", NULL);
+ else
+ index->idxname = NULL;
+
+ index->relname = stmt->relname;
+ index->accessMethod = "btree";
+ index->indexParams = NIL;
+ index->withClause = NIL;
+ index->whereClause = NULL;
+
+ keys = constraint->keys;
+ while (keys != NIL)
+ {
+ key = lfirst(keys);
+#if PARSEDEBUG
+printf("transformCreateStmt- check key %s for column match\n", key->name);
+#endif
+ columns = stmt->tableElts;
+ column = NULL;
+ while (columns != NIL)
+ {
+ column = lfirst(columns);
+#if PARSEDEBUG
+printf("transformCreateStmt- check column %s for key match\n", column->colname);
+#endif
+ if (strcasecmp(column->colname,key->name) == 0) break;
+ else column = NULL;
+ columns = lnext(columns);
+ }
+ if (column == NULL)
+ elog(WARN,"parser: column '%s' in key does not exist",key->name);
+
+ if (constraint->contype == CONSTR_PRIMARY)
+ {
+#if PARSEDEBUG
+printf("transformCreateStmt- mark column %s as NOT NULL\n", column->colname);
+#endif
+ column->is_not_null = TRUE;
+ }
+ iparam = makeNode(IndexElem);
+ iparam->name = strcpy(palloc(strlen(column->colname)+1), column->colname);
+ iparam->args = NIL;
+ iparam->class = NULL;
+ iparam->tname = NULL;
+ index->indexParams = lappend(index->indexParams, iparam);
+
+ if (index->idxname == NULL)
+ index->idxname = makeTableName(stmt->relname, iparam->name, "key", NULL);
+
+ keys = lnext(keys);
+ }
+
+ if (index->idxname == NULL)
+ elog(WARN,"parser: unable to construct implicit index for table %s"
+ "; name too long", stmt->relname);
+
+ dlist = lnext(dlist);
+ }
+
+ q->utilityStmt = (Node *) stmt;
+ extras = ilist;
+
+ return q;
+} /* transformCreateStmt() */
+
/*
* transformIndexStmt -
* transforms the qualification of the index statement
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.76 1997/12/04 00:26:57 scrappy Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.77 1997/12/04 23:07:23 thomas Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
#include "nodes/parsenodes.h"
#include "nodes/print.h"
#include "parser/gramparse.h"
+#include "parser/parse_type.h"
#include "utils/acl.h"
#include "utils/palloc.h"
#include "catalog/catname.h"
Attr *attr;
- ColumnDef *coldef;
- ConstraintDef *constrdef;
TypeName *typnam;
DefElem *defelt;
ParamString *param;
%type operation, TriggerOneEvent
%type stmtblock, stmtmulti,
- relation_name_list, OptTableElementList, tableElementList,
- OptInherit, OptConstraint, ConstraintList, definition,
+ relation_name_list, OptTableElementList,
+ OptInherit, definition,
opt_with, def_args, def_name_list, func_argtypes,
oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
opt_column_list, columnList, opt_va_list, va_list,
%type def_rest
-%type columnDef, alter_clause
+%type OptTableElement, ConstraintElem
+%type columnDef, alter_clause
%type def_elem
%type def_arg, columnElem, where_clause,
a_expr, a_expr_or_null, AexprConst,
%type Id, var_value, zone_value
%type ColId, ColLabel
-%type ConstraintElem, ConstraintDef
-
-%type constraint_elem
+%type TableConstraint
+%type constraint_expr
%type default_expr
-%type <str> opt_default
-%type <boolean> opt_constraint
+%type <list> ColQualList
+%type <node> ColConstraint, ColConstraintElem
%type key_actions, key_action
%type key_match, key_reference
*/
/* Keywords (in SQL92 reserved words) */
-%token ACTION, ADD, ALL, ALTER, AND, ARCHIVE, AS, ASC,
+%token ACTION, ADD, ALL, ALTER, AND, AS, ASC,
BEGIN_TRANS, BETWEEN, BOTH, BY,
CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED,
VACUUM, VERBOSE, VERSION
+/* Keywords (obsolete; retain temporarily for parser - thomas 1997-12-04) */
+%token ARCHIVE
+
/*
* Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
* when some sort of pg_privileges relation is introduced.
{
$$ = $3;
}
- | ADD '(' tableElementList ')'
+ | ADD '(' OptTableElementList ')'
{
- ColumnDef *lp = lfirst($3);
+ Node *lp = lfirst($3);
if (length($3) != 1)
elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
}
| DROP opt_column ColId
{ elog(WARN,"ALTER TABLE/DROP COLUMN not yet implemented",NULL); }
- | ALTER opt_column ColId SET opt_default
+ | ALTER opt_column ColId SET DEFAULT default_expr
{ elog(WARN,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented",NULL); }
| ALTER opt_column ColId DROP DEFAULT
{ elog(WARN,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented",NULL); }
{ elog(WARN,"ALTER TABLE/ADD CONSTRAINT not yet implemented",NULL); }
;
-columnDef: ColId Typename opt_default opt_constraint
- {
- $$ = makeNode(ColumnDef);
- $$->colname = $1;
- $$->typename = $2;
- $$->defval = $3;
- $$->is_not_null = $4;
- }
- ;
-
-opt_default: DEFAULT default_expr
- {
- $$ = FlattenStringList($2);
- }
- | /*EMPTY*/ { $$ = NULL; }
- ;
-
-default_expr: AexprConst
- { $$ = makeConstantList((A_Const *) $1); }
- | Pnull
- { $$ = lcons( makeString("NULL"), NIL); }
- | '-' 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
- { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
- | default_expr '<' default_expr
- { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
- | default_expr '>' default_expr
- { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
- | ':' 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
- {
- $4->name = fmtId($4->name);
- $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
- }
- | '(' default_expr ')'
- { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
- | name '(' default_expr ')'
- {
- $$ = makeList( makeString($1), makeString("("), -1);
- $$ = nconc( $$, $3);
- $$ = lappend( $$, makeString(")"));
- }
- | name '(' ')'
- {
- $$ = makeList( makeString($1), makeString("("), -1);
- $$ = lappend( $$, makeString(")"));
- }
- | default_expr Op default_expr
- {
- if (!strcmp("<=", $2) || !strcmp(">=", $2))
- elog(WARN,"boolean expressions not supported in DEFAULT",NULL);
- $$ = 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(p) precision must be zero",NULL);
- $$ = lcons( makeString( "'now'::time"), NIL);
- }
- | CURRENT_TIMESTAMP
- { $$ = lcons( makeString( "now()"), NIL); }
- | CURRENT_TIMESTAMP '(' Iconst ')'
- {
- if ($3 != 0)
- elog(NOTICE,"CURRENT_TIMESTAMP(p) precision must be zero",NULL);
- $$ = lcons( makeString( "now()"), NIL);
- }
- | CURRENT_USER
- { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
- ;
-
-opt_constraint: NOT NULL_P { $$ = TRUE; }
- | NOT NULL_P UNIQUE
- {
- elog(NOTICE,"UNIQUE clause ignored; not yet implemented",NULL);
- $$ = TRUE;
- }
- | NOTNULL { $$ = TRUE; }
- | UNIQUE
- {
- elog(NOTICE,"UNIQUE clause ignored; not yet implemented",NULL);
- $$ = FALSE;
- }
- | PRIMARY KEY
- {
- elog(NOTICE,"PRIMARY KEY clause ignored; not yet implemented",NULL);
- $$ = FALSE;
- }
- | REFERENCES ColId opt_column_list key_match key_actions
- {
- elog(NOTICE,"FOREIGN KEY clause ignored; not yet implemented",NULL);
- $$ = FALSE;
- }
- | /* EMPTY */ { $$ = FALSE; }
- ;
-
/*****************************************************************************
*
*****************************************************************************/
CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
- OptInherit OptConstraint OptArchiveType
+ OptInherit OptArchiveType
{
CreateStmt *n = makeNode(CreateStmt);
n->relname = $3;
n->tableElts = $5;
n->inhRelnames = $7;
- n->constraints = $8;
+ n->constraints = NIL;
$$ = (Node *)n;
}
;
-OptTableElementList: tableElementList { $$ = $1; }
- | /* EMPTY */ { $$ = NULL; }
+OptTableElementList: OptTableElementList ',' OptTableElement
+ { $$ = lappend($1, $3); }
+ | OptTableElement { $$ = lcons($1, NIL); }
+ | /*EMPTY*/ { $$ = NULL; }
;
-tableElementList :
- tableElementList ',' columnDef
- { $$ = lappend($1, $3); }
- | columnDef
- { $$ = lcons($1, NIL); }
+OptTableElement: columnDef { $$ = $1; }
+ | TableConstraint { $$ = $1; }
;
-/*
- * This was removed in 6.3, but we keep it so people can upgrade
- * with old pg_dump scripts.
+columnDef: ColId Typename ColQualList
+ {
+ ColumnDef *n = makeNode(ColumnDef);
+ n->colname = $1;
+ n->typename = $2;
+ n->defval = NULL;
+ n->is_not_null = FALSE;
+ n->constraints = $3;
+ $$ = (Node *)n;
+ }
+ ;
+
+/* ColQualList decodes column-specific qualifiers.
+ * Seem to need to specify the explicit combinations
+ * to eliminate reduce/reduce conflicts.
+ * I think this is because there are no explicit delimiters
+ * (like commas) between clauses.
+ * - thomas 1997-12-03
*/
-OptArchiveType: ARCHIVE '=' NONE { }
- | /*EMPTY*/ { }
+ColQualList: ColConstraint ColConstraint ColConstraint ColConstraint
+ { $$ = lappend(lappend(lappend(lcons($1, NIL), $2), $3), $4); }
+ | ColConstraint ColConstraint ColConstraint
+ { $$ = lappend(lappend(lcons($1, NIL), $2), $3); }
+ | ColConstraint ColConstraint { $$ = lappend(lcons($1, NIL), $2); }
+ | ColConstraint { $$ = lcons($1, NIL); }
+ | /*EMPTY*/ { $$ = NULL; }
;
-OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
- | /*EMPTY*/ { $$ = NIL; }
+ColConstraint:
+ CONSTRAINT name ColConstraintElem
+ {
+ Constraint *n = (Constraint *)$3;
+ n->name = fmtId($2);
+ $$ = $3;
+ }
+ | ColConstraintElem
+ { $$ = $1; }
;
-OptConstraint: ConstraintList { $$ = $1; }
- | /*EMPTY*/ { $$ = NULL; }
+ColConstraintElem: CHECK '(' constraint_expr ')'
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_CHECK;
+ n->name = NULL;
+ n->def = FlattenStringList($3);
+ n->keys = NULL;
+ $$ = (Node *)n;
+ }
+ | DEFAULT default_expr
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_DEFAULT;
+ n->name = NULL;
+ n->def = FlattenStringList($2);
+ n->keys = NULL;
+ $$ = (Node *)n;
+ }
+ | NOT NULL_P
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_NOTNULL;
+ n->name = NULL;
+ n->def = NULL;
+ n->keys = NULL;
+ $$ = (Node *)n;
+ }
+ | NOTNULL
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_NOTNULL;
+ n->name = NULL;
+ n->def = NULL;
+ n->keys = NULL;
+ $$ = (Node *)n;
+ }
+ | UNIQUE
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_UNIQUE;
+ n->name = NULL;
+ n->def = NULL;
+ n->keys = NULL;
+ $$ = (Node *)n;
+ }
+ | PRIMARY KEY
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_PRIMARY;
+ n->name = NULL;
+ n->def = NULL;
+ n->keys = NULL;
+ $$ = (Node *)n;
+ }
+ | REFERENCES ColId opt_column_list key_match key_actions
+ {
+ elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL);
+ $$ = NULL;
+ }
;
-ConstraintList:
- ConstraintList ',' ConstraintElem
- { $$ = lappend($1, $3); }
- | ConstraintElem
- { $$ = lcons($1, NIL); }
+default_expr: AexprConst
+ { $$ = makeConstantList((A_Const *) $1); }
+ | NULL_P
+ { $$ = lcons( makeString("NULL"), NIL); }
+ | '-' 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
+ { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
+ | default_expr '<' default_expr
+ { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
+ | default_expr '>' default_expr
+ { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
+ | ':' 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
+ {
+ $4->name = fmtId($4->name);
+ $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
+ }
+ | '(' default_expr ')'
+ { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
+ | name '(' default_expr ')'
+ {
+ $$ = makeList( makeString($1), makeString("("), -1);
+ $$ = nconc( $$, $3);
+ $$ = lappend( $$, makeString(")"));
+ }
+ | name '(' ')'
+ {
+ $$ = makeList( makeString($1), makeString("("), -1);
+ $$ = lappend( $$, makeString(")"));
+ }
+ | default_expr Op default_expr
+ {
+ if (!strcmp("<=", $2) || !strcmp(">=", $2))
+ elog(WARN,"boolean expressions not supported in DEFAULT",NULL);
+ $$ = 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); }
;
-ConstraintElem:
- CONSTRAINT name ConstraintDef
+/* ConstraintElem specifies constraint syntax which is not embedded into
+ * a column definition. ColConstraintElem specifies the embedded form.
+ * - thomas 1997-12-03
+ */
+TableConstraint: CONSTRAINT name ConstraintElem
{
- $3->name = fmtId($2);
+ Constraint *n = (Constraint *)$3;
+ n->name = fmtId($2);
$$ = $3;
}
- | ConstraintDef { $$ = $1; }
+ | ConstraintElem
+ { $$ = $1; }
;
-ConstraintDef: CHECK constraint_elem
+ConstraintElem: CHECK '(' constraint_expr ')'
{
- ConstraintDef *constr = palloc (sizeof(ConstraintDef));
- constr->type = CONSTR_CHECK;
- constr->name = NULL;
- constr->def = FlattenStringList($2);
- $$ = constr;
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_CHECK;
+ n->name = NULL;
+ n->def = FlattenStringList($3);
+ $$ = (Node *)n;
}
| UNIQUE '(' columnList ')'
- { elog(NOTICE,"CREATE TABLE/UNIQUE clause ignored; not yet implemented",NULL); }
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_UNIQUE;
+ n->name = NULL;
+ n->def = NULL;
+ n->keys = $3;
+ $$ = (Node *)n;
+ }
| PRIMARY KEY '(' columnList ')'
- { elog(NOTICE,"CREATE TABLE/PRIMARY KEY clause ignored; not yet implemented",NULL); }
+ {
+ Constraint *n = makeNode(Constraint);
+ n->contype = CONSTR_PRIMARY;
+ n->name = NULL;
+ n->def = NULL;
+ n->keys = $4;
+ $$ = (Node *)n;
+ }
| FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
{ elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL); }
;
-constraint_elem: AexprConst
+constraint_expr: AexprConst
{ $$ = makeConstantList((A_Const *) $1); }
- | Pnull
+ | NULL_P
{ $$ = lcons( makeString("NULL"), NIL); }
| ColId
{
$$ = lcons( makeString(fmtId($1)), NIL);
}
- | '-' constraint_elem %prec UMINUS
+ | '-' constraint_expr %prec UMINUS
{ $$ = lcons( makeString( "-"), $2); }
- | constraint_elem '+' constraint_elem
+ | constraint_expr '+' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "+"), $3)); }
- | constraint_elem '-' constraint_elem
+ | constraint_expr '-' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "-"), $3)); }
- | constraint_elem '/' constraint_elem
+ | constraint_expr '/' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "/"), $3)); }
- | constraint_elem '*' constraint_elem
+ | constraint_expr '*' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "*"), $3)); }
- | constraint_elem '=' constraint_elem
+ | constraint_expr '=' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "="), $3)); }
- | constraint_elem '<' constraint_elem
+ | constraint_expr '<' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "<"), $3)); }
- | constraint_elem '>' constraint_elem
+ | constraint_expr '>' constraint_expr
{ $$ = nconc( $1, lcons( makeString( ">"), $3)); }
- | ':' constraint_elem
+ | ':' constraint_expr
{ $$ = lcons( makeString( ":"), $2); }
- | ';' constraint_elem
+ | ';' constraint_expr
{ $$ = lcons( makeString( ";"), $2); }
- | '|' constraint_elem
+ | '|' constraint_expr
{ $$ = lcons( makeString( "|"), $2); }
- | constraint_elem TYPECAST Typename
+ | constraint_expr TYPECAST Typename
{
$3->name = fmtId($3->name);
$$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
}
- | CAST constraint_elem AS Typename
+ | CAST constraint_expr AS Typename
{
$4->name = fmtId($4->name);
$$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
}
- | '(' constraint_elem ')'
+ | '(' constraint_expr ')'
{ $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
- | name '(' constraint_elem ')'
+ | name '(' constraint_expr ')'
{
$$ = makeList( makeString($1), makeString("("), -1);
$$ = nconc( $$, $3);
$$ = lappend( $$, makeString(")"));
}
- | constraint_elem Op constraint_elem
+ | constraint_expr Op constraint_expr
{ $$ = nconc( $1, lcons( makeString( $2), $3)); }
- | constraint_elem AND constraint_elem
+ | constraint_expr AND constraint_expr
{ $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
- | constraint_elem OR constraint_elem
+ | constraint_expr OR constraint_expr
{ $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
- | Op constraint_elem
+ | Op constraint_expr
{ $$ = lcons( makeString( $1), $2); }
- | constraint_elem Op
+ | constraint_expr Op
{ $$ = lappend( $1, makeString( $2)); }
- | constraint_elem IS TRUE_P
+ | constraint_expr IS TRUE_P
{ $$ = lappend( $1, makeString( "IS TRUE")); }
- | constraint_elem IS FALSE_P
+ | constraint_expr IS FALSE_P
{ $$ = lappend( $1, makeString( "IS FALSE")); }
- | constraint_elem IS NOT TRUE_P
+ | constraint_expr IS NOT TRUE_P
{ $$ = lappend( $1, makeString( "IS NOT TRUE")); }
- | constraint_elem IS NOT FALSE_P
+ | constraint_expr IS NOT FALSE_P
{ $$ = lappend( $1, makeString( "IS NOT FALSE")); }
;
| SET NULL_P { $$ = NULL; }
;
+OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
+ | /*EMPTY*/ { $$ = NIL; }
+ ;
+
+/*
+ * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
+ * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
+ */
+OptArchiveType: ARCHIVE '=' NONE { }
+ | /*EMPTY*/ { }
+ ;
+
/*****************************************************************************
*
;
def_type: OPERATOR { $$ = OPERATOR; }
- | Type { $$ = TYPE_P; }
+ | TYPE_P { $$ = TYPE_P; }
| AGGREGATE { $$ = AGGREGATE; }
;
}
;
-remove_type: Type { $$ = TYPE_P; }
+remove_type: TYPE_P { $$ = TYPE_P; }
| INDEX { $$ = INDEX; }
| RULE { $$ = RULE; }
| VIEW { $$ = VIEW; }
a_expr_or_null: a_expr
{ $$ = $1;}
- | Pnull
+ | NULL_P
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
t->setof = FALSE;
if ($3 != 0)
- elog(NOTICE,"CURRENT_TIME(p) precision must be zero",NULL);
+ elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
$$ = (Node *)n;
}
t->setof = FALSE;
if ($3 != 0)
- elog(NOTICE,"CURRENT_TIMESTAMP(p) precision must be zero",NULL);
+ elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
$$ = (Node *)n;
}
}
;
-Type: TYPE_P;
-Pnull: NULL_P;
-
%%
static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)