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
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录