Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
9cad9feb
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,发现更多精彩内容 >>
提交
9cad9feb
编写于
8月 23, 1998
作者:
B
Bruce Momjian
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
cleanup
上级
985f4ab9
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
150 addition
and
151 deletion
+150
-151
src/backend/parser/README
src/backend/parser/README
+1
-1
src/backend/parser/parse_target.c
src/backend/parser/parse_target.c
+149
-150
未找到文件。
src/backend/parser/README
浏览文件 @
9cad9feb
...
...
@@ -9,11 +9,11 @@ keywords.c turn keywords into specific tokens
gram.y parse the tokens and fill query-type-specific structures
analyze.c handle post-parse processing for each query type
parse_clause.c handle clauses like WHERE, ORDER BY, GROUP BY, ...
parse_coerce.c used for coercing expressions of different types
parse_expr.c handle expressions like col, col + 3, x = 3 or x = 4
parse_oper.c handle operations in expressions
parse_agg.c handle aggregates, like SUM(col1), AVG(col2), ...
parse_func.c handle functions, table.column and column identifiers
parse_node.c create nodes for various structures
parse_target.c handle the result list of the query
parse_relation.c support routines for tables and column handling
...
...
src/backend/parser/parse_target.c
浏览文件 @
9cad9feb
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.2
1 1998/08/19 02:02:2
6 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.2
2 1998/08/23 14:43:4
6 momjian Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -187,6 +187,154 @@ printf("transformTargetIdent- attrtype_target = %d; type_mod = %d\n", attrtype_t
}
/* transformTargetIdent() */
/* MakeTargetlistExpr()
* Make a TargetEntry from an expression.
* arrayRef is a list of transformed A_Indices.
*
* For type mismatches between expressions and targets, use the same
* techniques as for function and operator type coersion.
* - thomas 1998-05-08
*
* Added resjunk flag and made extern so that it can be use by GROUP/
* ORDER BY a function or expersion not in the target_list
* - daveh@insightdist.com 1998-07-31
*/
TargetEntry
*
MakeTargetlistExpr
(
ParseState
*
pstate
,
char
*
colname
,
Node
*
expr
,
List
*
arrayRef
,
int16
resjunk
)
{
Oid
type_id
,
attrtype
;
int32
type_mod
,
attrtypmod
;
int
resdomno
;
Relation
rd
;
bool
attrisset
;
TargetEntry
*
tent
;
Resdom
*
resnode
;
if
(
expr
==
NULL
)
elog
(
ERROR
,
"MakeTargetlistExpr: invalid use of NULL expression"
);
type_id
=
exprType
(
expr
);
if
(
nodeTag
(
expr
)
==
T_Var
)
type_mod
=
((
Var
*
)
expr
)
->
vartypmod
;
else
type_mod
=
-
1
;
/* Processes target columns that will be receiving results */
if
(
pstate
->
p_is_insert
||
pstate
->
p_is_update
)
{
/*
* insert or update query -- insert, update work only on one
* relation, so multiple occurence of same resdomno is bogus
*/
rd
=
pstate
->
p_target_relation
;
Assert
(
rd
!=
NULL
);
resdomno
=
attnameAttNum
(
rd
,
colname
);
attrisset
=
attnameIsSet
(
rd
,
colname
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
if
((
arrayRef
!=
NIL
)
&&
(
lfirst
(
arrayRef
)
==
NIL
))
attrtype
=
GetArrayElementType
(
attrtype
);
attrtypmod
=
rd
->
rd_att
->
attrs
[
resdomno
-
1
]
->
atttypmod
;
/* Check for InvalidOid since that seems to indicate a NULL constant... */
if
(
type_id
!=
InvalidOid
)
{
/* Mismatch on types? then try to coerce to target... */
if
(
attrtype
!=
type_id
)
{
Oid
typelem
;
if
(
arrayRef
&&
!
(((
A_Indices
*
)
lfirst
(
arrayRef
))
->
lidx
))
typelem
=
typeidTypElem
(
attrtype
);
else
typelem
=
attrtype
;
expr
=
CoerceTargetExpr
(
pstate
,
expr
,
type_id
,
typelem
);
if
(
!
HeapTupleIsValid
(
expr
))
elog
(
ERROR
,
"parser: attribute '%s' is of type '%s'"
" but expression is of type '%s'"
"
\n\t
You will need to rewrite or cast the expression"
,
colname
,
typeidTypeName
(
attrtype
),
typeidTypeName
(
type_id
));
}
#ifdef PARSEDEBUG
printf
(
"MakeTargetlistExpr: attrtypmod is %d
\n
"
,
(
int4
)
attrtypmod
);
#endif
/* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
if
(
attrtypmod
>
0
)
expr
=
SizeTargetExpr
(
pstate
,
expr
,
attrtype
,
attrtypmod
);
}
if
(
arrayRef
!=
NIL
)
{
Expr
*
target_expr
;
Attr
*
att
=
makeNode
(
Attr
);
List
*
ar
=
arrayRef
;
List
*
upperIndexpr
=
NIL
;
List
*
lowerIndexpr
=
NIL
;
att
->
relname
=
pstrdup
(
RelationGetRelationName
(
rd
)
->
data
);
att
->
attrs
=
lcons
(
makeString
(
colname
),
NIL
);
target_expr
=
(
Expr
*
)
ParseNestedFuncOrColumn
(
pstate
,
att
,
&
pstate
->
p_last_resno
,
EXPR_COLUMN_FIRST
);
while
(
ar
!=
NIL
)
{
A_Indices
*
ind
=
lfirst
(
ar
);
if
(
lowerIndexpr
||
(
!
upperIndexpr
&&
ind
->
lidx
))
{
/*
* XXX assume all lowerIndexpr is non-null in this
* case
*/
lowerIndexpr
=
lappend
(
lowerIndexpr
,
ind
->
lidx
);
}
upperIndexpr
=
lappend
(
upperIndexpr
,
ind
->
uidx
);
ar
=
lnext
(
ar
);
}
expr
=
(
Node
*
)
make_array_set
(
target_expr
,
upperIndexpr
,
lowerIndexpr
,
(
Expr
*
)
expr
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
attrtypmod
=
get_atttypmod
(
RelationGetRelid
(
rd
),
resdomno
);
}
}
else
{
resdomno
=
pstate
->
p_last_resno
++
;
attrtype
=
type_id
;
attrtypmod
=
type_mod
;
}
resnode
=
makeResdom
((
AttrNumber
)
resdomno
,
(
Oid
)
attrtype
,
attrtypmod
,
colname
,
(
Index
)
0
,
(
Oid
)
0
,
resjunk
);
tent
=
makeTargetEntry
(
resnode
,
expr
);
return
tent
;
}
/* MakeTargetlistExpr() */
/* transformTargetList()
* Turns a list of ResTarget's into a list of TargetEntry's.
*/
...
...
@@ -299,7 +447,6 @@ printf("transformTargetList: decode T_Expr\n");
/* this is not an array assignment */
if
(
colname
==
NULL
)
{
/*
* if you're wondering why this is here, look
* at the yacc grammar for why a name can be
...
...
@@ -559,154 +706,6 @@ printf("SizeTargetExpr: no conversion function for sizing\n");
}
/* SizeTargetExpr() */
/* MakeTargetlistExpr()
* Make a TargetEntry from an expression.
* arrayRef is a list of transformed A_Indices.
*
* For type mismatches between expressions and targets, use the same
* techniques as for function and operator type coersion.
* - thomas 1998-05-08
*
* Added resjunk flag and made extern so that it can be use by GROUP/
* ORDER BY a function or expersion not in the target_list
* - daveh@insightdist.com 1998-07-31
*/
TargetEntry
*
MakeTargetlistExpr
(
ParseState
*
pstate
,
char
*
colname
,
Node
*
expr
,
List
*
arrayRef
,
int16
resjunk
)
{
Oid
type_id
,
attrtype
;
int32
type_mod
,
attrtypmod
;
int
resdomno
;
Relation
rd
;
bool
attrisset
;
TargetEntry
*
tent
;
Resdom
*
resnode
;
if
(
expr
==
NULL
)
elog
(
ERROR
,
"MakeTargetlistExpr: invalid use of NULL expression"
);
type_id
=
exprType
(
expr
);
if
(
nodeTag
(
expr
)
==
T_Var
)
type_mod
=
((
Var
*
)
expr
)
->
vartypmod
;
else
type_mod
=
-
1
;
/* Processes target columns that will be receiving results */
if
(
pstate
->
p_is_insert
||
pstate
->
p_is_update
)
{
/*
* insert or update query -- insert, update work only on one
* relation, so multiple occurence of same resdomno is bogus
*/
rd
=
pstate
->
p_target_relation
;
Assert
(
rd
!=
NULL
);
resdomno
=
attnameAttNum
(
rd
,
colname
);
attrisset
=
attnameIsSet
(
rd
,
colname
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
if
((
arrayRef
!=
NIL
)
&&
(
lfirst
(
arrayRef
)
==
NIL
))
attrtype
=
GetArrayElementType
(
attrtype
);
attrtypmod
=
rd
->
rd_att
->
attrs
[
resdomno
-
1
]
->
atttypmod
;
/* Check for InvalidOid since that seems to indicate a NULL constant... */
if
(
type_id
!=
InvalidOid
)
{
/* Mismatch on types? then try to coerce to target... */
if
(
attrtype
!=
type_id
)
{
Oid
typelem
;
if
(
arrayRef
&&
!
(((
A_Indices
*
)
lfirst
(
arrayRef
))
->
lidx
))
typelem
=
typeidTypElem
(
attrtype
);
else
typelem
=
attrtype
;
expr
=
CoerceTargetExpr
(
pstate
,
expr
,
type_id
,
typelem
);
if
(
!
HeapTupleIsValid
(
expr
))
elog
(
ERROR
,
"parser: attribute '%s' is of type '%s'"
" but expression is of type '%s'"
"
\n\t
You will need to rewrite or cast the expression"
,
colname
,
typeidTypeName
(
attrtype
),
typeidTypeName
(
type_id
));
}
#ifdef PARSEDEBUG
printf
(
"MakeTargetlistExpr: attrtypmod is %d
\n
"
,
(
int4
)
attrtypmod
);
#endif
/* Apparently going to a fixed-length string?
* Then explicitly size for storage...
*/
if
(
attrtypmod
>
0
)
expr
=
SizeTargetExpr
(
pstate
,
expr
,
attrtype
,
attrtypmod
);
}
if
(
arrayRef
!=
NIL
)
{
Expr
*
target_expr
;
Attr
*
att
=
makeNode
(
Attr
);
List
*
ar
=
arrayRef
;
List
*
upperIndexpr
=
NIL
;
List
*
lowerIndexpr
=
NIL
;
att
->
relname
=
pstrdup
(
RelationGetRelationName
(
rd
)
->
data
);
att
->
attrs
=
lcons
(
makeString
(
colname
),
NIL
);
target_expr
=
(
Expr
*
)
ParseNestedFuncOrColumn
(
pstate
,
att
,
&
pstate
->
p_last_resno
,
EXPR_COLUMN_FIRST
);
while
(
ar
!=
NIL
)
{
A_Indices
*
ind
=
lfirst
(
ar
);
if
(
lowerIndexpr
||
(
!
upperIndexpr
&&
ind
->
lidx
))
{
/*
* XXX assume all lowerIndexpr is non-null in this
* case
*/
lowerIndexpr
=
lappend
(
lowerIndexpr
,
ind
->
lidx
);
}
upperIndexpr
=
lappend
(
upperIndexpr
,
ind
->
uidx
);
ar
=
lnext
(
ar
);
}
expr
=
(
Node
*
)
make_array_set
(
target_expr
,
upperIndexpr
,
lowerIndexpr
,
(
Expr
*
)
expr
);
attrtype
=
attnumTypeId
(
rd
,
resdomno
);
attrtypmod
=
get_atttypmod
(
RelationGetRelid
(
rd
),
resdomno
);
}
}
else
{
resdomno
=
pstate
->
p_last_resno
++
;
attrtype
=
type_id
;
attrtypmod
=
type_mod
;
}
resnode
=
makeResdom
((
AttrNumber
)
resdomno
,
(
Oid
)
attrtype
,
attrtypmod
,
colname
,
(
Index
)
0
,
(
Oid
)
0
,
resjunk
);
tent
=
makeTargetEntry
(
resnode
,
expr
);
return
tent
;
}
/* MakeTargetlistExpr() */
/*
* makeTargetNames -
* generate a list of column names if not supplied or
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录