Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Greenplum
Gpdb
提交
fabef304
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,发现更多精彩内容 >>
提交
fabef304
编写于
5月 14, 2005
作者:
T
Tom Lane
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Minor refactoring to eliminate duplicate code and make startup a
tad faster.
上级
05b4293b
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
161 addition
and
214 deletion
+161
-214
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeMergejoin.c
+156
-213
src/include/nodes/execnodes.h
src/include/nodes/execnodes.h
+5
-1
未找到文件。
src/backend/executor/nodeMergejoin.c
浏览文件 @
fabef304
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.7
2 2005/05/13 21:20:16
tgl Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeMergejoin.c,v 1.7
3 2005/05/14 21:29:23
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -525,6 +525,86 @@ MJCompare(MergeJoinState *mergestate)
return
result
;
}
/*
* Generate a fake join tuple with nulls for the inner tuple,
* and return it if it passes the non-join quals.
*/
static
TupleTableSlot
*
MJFillOuter
(
MergeJoinState
*
node
)
{
ExprContext
*
econtext
=
node
->
js
.
ps
.
ps_ExprContext
;
List
*
otherqual
=
node
->
js
.
ps
.
qual
;
ResetExprContext
(
econtext
);
econtext
->
ecxt_outertuple
=
node
->
mj_OuterTupleSlot
;
econtext
->
ecxt_innertuple
=
node
->
mj_NullInnerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired projection tuple
* and return the slot containing it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
MJ_printf
(
"ExecMergeJoin: returning outer fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
return
NULL
;
}
/*
* Generate a fake join tuple with nulls for the outer tuple,
* and return it if it passes the non-join quals.
*/
static
TupleTableSlot
*
MJFillInner
(
MergeJoinState
*
node
)
{
ExprContext
*
econtext
=
node
->
js
.
ps
.
ps_ExprContext
;
List
*
otherqual
=
node
->
js
.
ps
.
qual
;
ResetExprContext
(
econtext
);
econtext
->
ecxt_outertuple
=
node
->
mj_NullOuterTupleSlot
;
econtext
->
ecxt_innertuple
=
node
->
mj_InnerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired projection tuple
* and return the slot containing it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
MJ_printf
(
"ExecMergeJoin: returning inner fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
return
NULL
;
}
/* ----------------------------------------------------------------
* ExecMergeTupleDump
*
...
...
@@ -612,33 +692,8 @@ ExecMergeJoin(MergeJoinState *node)
econtext
=
node
->
js
.
ps
.
ps_ExprContext
;
joinqual
=
node
->
js
.
joinqual
;
otherqual
=
node
->
js
.
ps
.
qual
;
switch
(
node
->
js
.
jointype
)
{
case
JOIN_INNER
:
case
JOIN_IN
:
doFillOuter
=
false
;
doFillInner
=
false
;
break
;
case
JOIN_LEFT
:
doFillOuter
=
true
;
doFillInner
=
false
;
break
;
case
JOIN_FULL
:
doFillOuter
=
true
;
doFillInner
=
true
;
break
;
case
JOIN_RIGHT
:
doFillOuter
=
false
;
doFillInner
=
true
;
break
;
default:
elog
(
ERROR
,
"unrecognized join type: %d"
,
(
int
)
node
->
js
.
jointype
);
doFillOuter
=
false
;
/* keep compiler quiet */
doFillInner
=
false
;
break
;
}
doFillOuter
=
node
->
mj_FillOuter
;
doFillInner
=
node
->
mj_FillInner
;
/*
* Check to see if we're still projecting out tuples from a previous
...
...
@@ -707,15 +762,27 @@ ExecMergeJoin(MergeJoinState *node)
}
/* Compute join values and check for unmatchability */
if
(
!
MJEvalOuterValues
(
node
)
&&
!
doFillOuter
)
if
(
MJEvalOuterValues
(
node
)
)
{
/*
Stay in same state to fetch next out
er tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_
OUT
ER
;
/*
OK to go get the first inn
er tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_
INN
ER
;
}
else
{
/* OK to go get the first inner tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_INNER
;
/* Stay in same state to fetch next outer tuple */
if
(
doFillOuter
)
{
/*
* Generate a fake join tuple with nulls for the inner
* tuple, and return it if it passes the non-join
* quals.
*/
TupleTableSlot
*
result
;
result
=
MJFillOuter
(
node
);
if
(
result
)
return
result
;
}
}
break
;
...
...
@@ -745,12 +812,7 @@ ExecMergeJoin(MergeJoinState *node)
}
/* Compute join values and check for unmatchability */
if
(
!
MJEvalInnerValues
(
node
,
innerTupleSlot
)
&&
!
doFillInner
)
{
/* Stay in same state to fetch next inner tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_INNER
;
}
else
if
(
MJEvalInnerValues
(
node
,
innerTupleSlot
))
{
/*
* OK, we have the initial tuples. Begin by skipping
...
...
@@ -758,6 +820,23 @@ ExecMergeJoin(MergeJoinState *node)
*/
node
->
mj_JoinState
=
EXEC_MJ_SKIP_TEST
;
}
else
{
/* Stay in same state to fetch next inner tuple */
if
(
doFillInner
)
{
/*
* Generate a fake join tuple with nulls for the outer
* tuple, and return it if it passes the non-join
* quals.
*/
TupleTableSlot
*
result
;
result
=
MJFillInner
(
node
);
if
(
result
)
return
result
;
}
}
break
;
/*
...
...
@@ -856,37 +935,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* quals.
*/
node
->
mj_MatchedInner
=
true
;
/* do it only once */
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_NullOuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_InnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
TupleTableSlot
*
result
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired
* projection tuple and return the slot containing
* it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
node
->
mj_MatchedInner
=
true
;
/* do it only once */
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
result
=
MJFillInner
(
node
);
if
(
result
)
return
result
;
}
/*
...
...
@@ -961,37 +1016,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* quals.
*/
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_OuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_NullInnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired
* projection tuple and return the slot containing
* it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
result
=
MJFillOuter
(
node
);
if
(
result
)
return
result
;
}
/*
...
...
@@ -1223,37 +1254,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* quals.
*/
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_OuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_NullInnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired
* projection tuple and return the slot containing
* it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
TupleTableSlot
*
result
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
result
=
MJFillOuter
(
node
);
if
(
result
)
return
result
;
}
/*
...
...
@@ -1311,37 +1318,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* quals.
*/
node
->
mj_MatchedInner
=
true
;
/* do it only once */
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_NullOuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_InnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired
* projection tuple and return the slot containing
* it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
TupleTableSlot
*
result
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
node
->
mj_MatchedInner
=
true
;
/* do it only once */
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
result
=
MJFillInner
(
node
);
if
(
result
)
return
result
;
}
/*
...
...
@@ -1402,37 +1385,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* quals.
*/
node
->
mj_MatchedInner
=
true
;
/* do it only once */
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_NullOuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_InnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
TupleTableSlot
*
result
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired
* projection tuple and return the slot containing
* it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
node
->
mj_MatchedInner
=
true
;
/* do it only once */
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
result
=
MJFillInner
(
node
);
if
(
result
)
return
result
;
}
/*
...
...
@@ -1469,37 +1428,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* quals.
*/
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_OuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_NullInnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
{
/*
* qualification succeeded. now form the desired
* projection tuple and return the slot containing
* it.
*/
TupleTableSlot
*
result
;
ExprDoneCond
isDone
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
if
(
isDone
!=
ExprEndResult
)
{
node
->
js
.
ps
.
ps_TupFromTlist
=
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
result
=
MJFillOuter
(
node
);
if
(
result
)
return
result
;
}
/*
...
...
@@ -1601,13 +1536,19 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
{
case
JOIN_INNER
:
case
JOIN_IN
:
mergestate
->
mj_FillOuter
=
false
;
mergestate
->
mj_FillInner
=
false
;
break
;
case
JOIN_LEFT
:
mergestate
->
mj_FillOuter
=
true
;
mergestate
->
mj_FillInner
=
false
;
mergestate
->
mj_NullInnerTupleSlot
=
ExecInitNullTupleSlot
(
estate
,
ExecGetResultType
(
innerPlanState
(
mergestate
)));
break
;
case
JOIN_RIGHT
:
mergestate
->
mj_FillOuter
=
false
;
mergestate
->
mj_FillInner
=
true
;
mergestate
->
mj_NullOuterTupleSlot
=
ExecInitNullTupleSlot
(
estate
,
ExecGetResultType
(
outerPlanState
(
mergestate
)));
...
...
@@ -1622,6 +1563,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
errmsg
(
"RIGHT JOIN is only supported with merge-joinable join conditions"
)));
break
;
case
JOIN_FULL
:
mergestate
->
mj_FillOuter
=
true
;
mergestate
->
mj_FillInner
=
true
;
mergestate
->
mj_NullOuterTupleSlot
=
ExecInitNullTupleSlot
(
estate
,
ExecGetResultType
(
outerPlanState
(
mergestate
)));
...
...
src/include/nodes/execnodes.h
浏览文件 @
fabef304
...
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.13
2 2005/05/13 21:20:16
tgl Exp $
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.13
3 2005/05/14 21:29:23
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -1031,6 +1031,8 @@ typedef struct NestLoopState
* NumClauses number of mergejoinable join clauses
* Clauses info for each mergejoinable clause
* JoinState current "state" of join. see execdefs.h
* FillOuter true if should emit unjoined outer tuples anyway
* FillInner true if should emit unjoined inner tuples anyway
* MatchedOuter true if found a join match for current outer tuple
* MatchedInner true if found a join match for current inner tuple
* OuterTupleSlot slot in tuple table for cur outer tuple
...
...
@@ -1051,6 +1053,8 @@ typedef struct MergeJoinState
int
mj_NumClauses
;
MergeJoinClause
mj_Clauses
;
/* array of length mj_NumClauses */
int
mj_JoinState
;
bool
mj_FillOuter
;
bool
mj_FillInner
;
bool
mj_MatchedOuter
;
bool
mj_MatchedInner
;
TupleTableSlot
*
mj_OuterTupleSlot
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录