Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
1ac4ae49
G
Gpdb
项目概览
Greenplum
/
Gpdb
通知
7
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
Gpdb
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1ac4ae49
编写于
12月 04, 1997
作者:
T
Thomas G. Lockhart
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add SQL92-compliant syntax for constraints.
Implement PRIMARY KEY and UNIQUE clauses using indices.
上级
7b06d995
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
601 addition
and
209 deletion
+601
-209
src/backend/parser/analyze.c
src/backend/parser/analyze.c
+329
-1
src/backend/parser/gram.y
src/backend/parser/gram.y
+272
-208
未找到文件。
src/backend/parser/analyze.c
浏览文件 @
1ac4ae49
...
...
@@ -7,13 +7,14 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.5
1 1997/11/26 01:11:03 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.5
2 1997/12/04 23:07:18 thomas
Exp $
*
*-------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include "postgres.h"
...
...
@@ -39,7 +40,9 @@ static Query *transformRuleStmt(ParseState *query, RuleStmt *stmt);
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 -
...
...
@@ -65,6 +68,17 @@ parse_analyze(List *pl)
{
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
);
...
...
@@ -90,6 +104,10 @@ transformStmt(ParseState *pstate, Node *parseTree)
* Non-optimizable statements
*------------------------
*/
case
T_CreateStmt
:
result
=
transformCreateStmt
(
pstate
,
(
CreateStmt
*
)
parseTree
);
break
;
case
T_IndexStmt
:
result
=
transformIndexStmt
(
pstate
,
(
IndexStmt
*
)
parseTree
);
break
;
...
...
@@ -309,6 +327,316 @@ transformInsertStmt(ParseState *pstate, AppendStmt *stmt)
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
...
...
src/backend/parser/gram.y
浏览文件 @
1ac4ae49
...
...
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.7
6 1997/12/04 00:26:57 scrappy
Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.7
7 1997/12/04 23:07:23 thomas
Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
...
...
@@ -39,6 +39,7 @@
#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"
...
...
@@ -91,8 +92,6 @@ Oid param_type(int t); /* used in parse_expr.c */
Attr *attr;
ColumnDef *coldef;
ConstraintDef *constrdef;
TypeName *typnam;
DefElem *defelt;
ParamString *param;
...
...
@@ -149,8 +148,8 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <chr> operation, TriggerOneEvent
%type <list> 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,
...
...
@@ -184,7 +183,8 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <dstmt> def_rest
%type <astmt> insert_rest
%type <coldef> columnDef, alter_clause
%type <node> OptTableElement, ConstraintElem
%type <node> columnDef, alter_clause
%type <defelt> def_elem
%type <node> def_arg, columnElem, where_clause,
a_expr, a_expr_or_null, AexprConst,
...
...
@@ -211,12 +211,11 @@ Oid param_type(int t); /* used in parse_expr.c */
%type <str> Id, var_value, zone_value
%type <str> ColId, ColLabel
%type <constrdef> ConstraintElem, ConstraintDef
%type <list> constraint_elem
%type <node> TableConstraint
%type <list> constraint_expr
%type <list> default_expr
%type <
str> opt_defaul
t
%type <
boolean> opt_constraint
%type <
list> ColQualLis
t
%type <
node> ColConstraint, ColConstraintElem
%type <list> key_actions, key_action
%type <str> key_match, key_reference
...
...
@@ -236,7 +235,7 @@ Oid param_type(int t); /* used in parse_expr.c */
*/
/* Keywords (in SQL92 reserved words) */
%token ACTION, ADD, ALL, ALTER, AND, A
RCHIVE, A
S, 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,
...
...
@@ -276,6 +275,9 @@ Oid param_type(int t); /* used in parse_expr.c */
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.
...
...
@@ -566,9 +568,9 @@ alter_clause: ADD opt_column columnDef
{
$$ = $3;
}
| ADD '('
t
ableElementList ')'
| ADD '('
OptT
ableElementList ')'
{
ColumnDef
*lp = lfirst($3);
Node
*lp = lfirst($3);
if (length($3) != 1)
elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
...
...
@@ -576,7 +578,7 @@ alter_clause: ADD opt_column columnDef
}
| 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); }
...
...
@@ -584,130 +586,6 @@ alter_clause: ADD opt_column columnDef
{ 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; }
;
/*****************************************************************************
*
...
...
@@ -786,141 +664,318 @@ copy_delimiter: USING DELIMITERS Sconst { $$ = $3;}
*****************************************************************************/
CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
OptInherit Opt
Constraint Opt
ArchiveType
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; }
;
Constraint
Def: CHECK constraint_elem
Constraint
Elem: CHECK '(' constraint_expr ')'
{
Constraint
Def *constr = palloc (sizeof(ConstraintDef)
);
constr->
type = CONSTR_CHECK;
constr
->name = NULL;
constr->def = FlattenStringList($2
);
$$ =
constr
;
Constraint
*n = makeNode(Constraint
);
n->con
type = 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_e
lem
: AexprConst
constraint_e
xpr
: AexprConst
{ $$ = makeConstantList((A_Const *) $1); }
|
Pnull
|
NULL_P
{ $$ = lcons( makeString("NULL"), NIL); }
| ColId
{
$$ = lcons( makeString(fmtId($1)), NIL);
}
| '-' constraint_e
lem
%prec UMINUS
| '-' constraint_e
xpr
%prec UMINUS
{ $$ = lcons( makeString( "-"), $2); }
| constraint_e
lem '+' constraint_elem
| constraint_e
xpr '+' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "+"), $3)); }
| constraint_e
lem '-' constraint_elem
| constraint_e
xpr '-' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "-"), $3)); }
| constraint_e
lem '/' constraint_elem
| constraint_e
xpr '/' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "/"), $3)); }
| constraint_e
lem '*' constraint_elem
| constraint_e
xpr '*' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "*"), $3)); }
| constraint_e
lem '=' constraint_elem
| constraint_e
xpr '=' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "="), $3)); }
| constraint_e
lem '<' constraint_elem
| constraint_e
xpr '<' constraint_expr
{ $$ = nconc( $1, lcons( makeString( "<"), $3)); }
| constraint_e
lem '>' constraint_elem
| constraint_e
xpr '>' constraint_expr
{ $$ = nconc( $1, lcons( makeString( ">"), $3)); }
| ':' constraint_e
lem
| ':' constraint_e
xpr
{ $$ = lcons( makeString( ":"), $2); }
| ';' constraint_e
lem
| ';' constraint_e
xpr
{ $$ = lcons( makeString( ";"), $2); }
| '|' constraint_e
lem
| '|' constraint_e
xpr
{ $$ = lcons( makeString( "|"), $2); }
| constraint_e
lem
TYPECAST Typename
| constraint_e
xpr
TYPECAST Typename
{
$3->name = fmtId($3->name);
$$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
}
| CAST constraint_e
lem
AS Typename
| CAST constraint_e
xpr
AS Typename
{
$4->name = fmtId($4->name);
$$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
}
| '(' constraint_e
lem
')'
| '(' constraint_e
xpr
')'
{ $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
| name '(' constraint_e
lem
')'
| name '(' constraint_e
xpr
')'
{
$$ = makeList( makeString($1), makeString("("), -1);
$$ = nconc( $$, $3);
$$ = lappend( $$, makeString(")"));
}
| constraint_e
lem Op constraint_elem
| constraint_e
xpr Op constraint_expr
{ $$ = nconc( $1, lcons( makeString( $2), $3)); }
| constraint_e
lem AND constraint_elem
| constraint_e
xpr AND constraint_expr
{ $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
| constraint_e
lem OR constraint_elem
| constraint_e
xpr OR constraint_expr
{ $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
| Op constraint_e
lem
| Op constraint_e
xpr
{ $$ = lcons( makeString( $1), $2); }
| constraint_e
lem
Op
| constraint_e
xpr
Op
{ $$ = lappend( $1, makeString( $2)); }
| constraint_e
lem
IS TRUE_P
| constraint_e
xpr
IS TRUE_P
{ $$ = lappend( $1, makeString( "IS TRUE")); }
| constraint_e
lem
IS FALSE_P
| constraint_e
xpr
IS FALSE_P
{ $$ = lappend( $1, makeString( "IS FALSE")); }
| constraint_e
lem
IS NOT TRUE_P
| constraint_e
xpr
IS NOT TRUE_P
{ $$ = lappend( $1, makeString( "IS NOT TRUE")); }
| constraint_e
lem
IS NOT FALSE_P
| constraint_e
xpr
IS NOT FALSE_P
{ $$ = lappend( $1, makeString( "IS NOT FALSE")); }
;
...
...
@@ -944,6 +999,18 @@ key_reference: NO ACTION { $$ = NULL; }
| 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*/ { }
;
/*****************************************************************************
*
...
...
@@ -1133,7 +1200,7 @@ def_rest: def_name definition
;
def_type: OPERATOR { $$ = OPERATOR; }
| T
ype
{ $$ = TYPE_P; }
| T
YPE_P
{ $$ = TYPE_P; }
| AGGREGATE { $$ = AGGREGATE; }
;
...
...
@@ -1537,7 +1604,7 @@ RemoveStmt: DROP remove_type name
}
;
remove_type: T
ype
{ $$ = TYPE_P; }
remove_type: T
YPE_P
{ $$ = TYPE_P; }
| INDEX { $$ = INDEX; }
| RULE { $$ = RULE; }
| VIEW { $$ = VIEW; }
...
...
@@ -2694,7 +2761,7 @@ opt_interval: datetime { $$ = lcons($1, NIL); }
a_expr_or_null: a_expr
{ $$ = $1;}
|
Pnull
|
NULL_P
{
A_Const *n = makeNode(A_Const);
n->val.type = T_Null;
...
...
@@ -2845,7 +2912,7 @@ a_expr: attr opt_indirection
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;
}
...
...
@@ -2880,7 +2947,7 @@ a_expr: attr opt_indirection
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;
}
...
...
@@ -3566,9 +3633,6 @@ SpecialRuleRelation: CURRENT
}
;
Type: TYPE_P;
Pnull: NULL_P;
%%
static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录