Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
fabef304
Commit
fabef304
authored
May 14, 2005
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Minor refactoring to eliminate duplicate code and make startup a
tad faster.
parent
05b4293b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
161 additions
and
214 deletions
+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
No files found.
src/backend/executor/nodeMergejoin.c
View file @
fabef304
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
*
*
* IDENTIFICATION
* 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)
...
@@ -525,6 +525,86 @@ MJCompare(MergeJoinState *mergestate)
return
result
;
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
* ExecMergeTupleDump
*
*
...
@@ -612,33 +692,8 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -612,33 +692,8 @@ ExecMergeJoin(MergeJoinState *node)
econtext
=
node
->
js
.
ps
.
ps_ExprContext
;
econtext
=
node
->
js
.
ps
.
ps_ExprContext
;
joinqual
=
node
->
js
.
joinqual
;
joinqual
=
node
->
js
.
joinqual
;
otherqual
=
node
->
js
.
ps
.
qual
;
otherqual
=
node
->
js
.
ps
.
qual
;
doFillOuter
=
node
->
mj_FillOuter
;
switch
(
node
->
js
.
jointype
)
doFillInner
=
node
->
mj_FillInner
;
{
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
;
}
/*
/*
* Check to see if we're still projecting out tuples from a previous
* Check to see if we're still projecting out tuples from a previous
...
@@ -707,15 +762,27 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -707,15 +762,27 @@ ExecMergeJoin(MergeJoinState *node)
}
}
/* Compute join values and check for unmatchability */
/* Compute join values and check for unmatchability */
if
(
!
MJEvalOuterValues
(
node
)
&&
!
doFillOuter
)
if
(
MJEvalOuterValues
(
node
)
)
{
{
/*
Stay in same state to fetch next out
er tuple */
/*
OK to go get the first inn
er tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_
OUT
ER
;
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_
INN
ER
;
}
}
else
else
{
{
/* OK to go get the first inner tuple */
/* Stay in same state to fetch next outer tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_INNER
;
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
;
break
;
...
@@ -745,12 +812,7 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -745,12 +812,7 @@ ExecMergeJoin(MergeJoinState *node)
}
}
/* Compute join values and check for unmatchability */
/* Compute join values and check for unmatchability */
if
(
!
MJEvalInnerValues
(
node
,
innerTupleSlot
)
&&
!
doFillInner
)
if
(
MJEvalInnerValues
(
node
,
innerTupleSlot
))
{
/* Stay in same state to fetch next inner tuple */
node
->
mj_JoinState
=
EXEC_MJ_INITIALIZE_INNER
;
}
else
{
{
/*
/*
* OK, we have the initial tuples. Begin by skipping
* OK, we have the initial tuples. Begin by skipping
...
@@ -758,6 +820,23 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -758,6 +820,23 @@ ExecMergeJoin(MergeJoinState *node)
*/
*/
node
->
mj_JoinState
=
EXEC_MJ_SKIP_TEST
;
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
;
break
;
/*
/*
...
@@ -856,37 +935,13 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -856,37 +935,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* tuple, and return it if it passes the non-join
* quals.
* quals.
*/
*/
node
->
mj_MatchedInner
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_NullOuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_InnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
node
->
mj_MatchedInner
=
true
;
/* do it only once */
{
/*
* 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
);
if
(
isDone
!=
ExprEndResult
)
result
=
MJFillInner
(
node
);
{
if
(
result
)
node
->
js
.
ps
.
ps_TupFromTlist
=
return
result
;
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
}
}
/*
/*
...
@@ -961,37 +1016,13 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -961,37 +1016,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* tuple, and return it if it passes the non-join
* quals.
* quals.
*/
*/
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
ResetExprContext
(
econtext
);
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
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
);
if
(
isDone
!=
ExprEndResult
)
result
=
MJFillOuter
(
node
);
{
if
(
result
)
node
->
js
.
ps
.
ps_TupFromTlist
=
return
result
;
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
}
}
/*
/*
...
@@ -1223,37 +1254,13 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -1223,37 +1254,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* tuple, and return it if it passes the non-join
* quals.
* 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
"
);
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
if
(
isDone
!=
ExprEndResult
)
result
=
MJFillOuter
(
node
);
{
if
(
result
)
node
->
js
.
ps
.
ps_TupFromTlist
=
return
result
;
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
}
}
/*
/*
...
@@ -1311,37 +1318,13 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -1311,37 +1318,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* tuple, and return it if it passes the non-join
* quals.
* quals.
*/
*/
node
->
mj_MatchedInner
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
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
;
MJ_printf
(
"ExecMergeJoin: returning fill tuple
\n
"
);
node
->
mj_MatchedInner
=
true
;
/* do it only once */
result
=
ExecProject
(
node
->
js
.
ps
.
ps_ProjInfo
,
&
isDone
);
if
(
isDone
!=
ExprEndResult
)
result
=
MJFillInner
(
node
);
{
if
(
result
)
node
->
js
.
ps
.
ps_TupFromTlist
=
return
result
;
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
}
}
/*
/*
...
@@ -1402,37 +1385,13 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -1402,37 +1385,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* tuple, and return it if it passes the non-join
* quals.
* quals.
*/
*/
node
->
mj_MatchedInner
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
ResetExprContext
(
econtext
);
outerTupleSlot
=
node
->
mj_NullOuterTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
innerTupleSlot
=
node
->
mj_InnerTupleSlot
;
econtext
->
ecxt_innertuple
=
innerTupleSlot
;
if
(
ExecQual
(
otherqual
,
econtext
,
false
))
node
->
mj_MatchedInner
=
true
;
/* do it only once */
{
/*
* 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
);
if
(
isDone
!=
ExprEndResult
)
result
=
MJFillInner
(
node
);
{
if
(
result
)
node
->
js
.
ps
.
ps_TupFromTlist
=
return
result
;
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
}
}
/*
/*
...
@@ -1469,37 +1428,13 @@ ExecMergeJoin(MergeJoinState *node)
...
@@ -1469,37 +1428,13 @@ ExecMergeJoin(MergeJoinState *node)
* tuple, and return it if it passes the non-join
* tuple, and return it if it passes the non-join
* quals.
* quals.
*/
*/
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
TupleTableSlot
*
result
;
ResetExprContext
(
econtext
);
node
->
mj_MatchedOuter
=
true
;
/* do it only once */
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
);
if
(
isDone
!=
ExprEndResult
)
result
=
MJFillOuter
(
node
);
{
if
(
result
)
node
->
js
.
ps
.
ps_TupFromTlist
=
return
result
;
(
isDone
==
ExprMultipleResult
);
return
result
;
}
}
}
}
/*
/*
...
@@ -1601,13 +1536,19 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
...
@@ -1601,13 +1536,19 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
{
{
case
JOIN_INNER
:
case
JOIN_INNER
:
case
JOIN_IN
:
case
JOIN_IN
:
mergestate
->
mj_FillOuter
=
false
;
mergestate
->
mj_FillInner
=
false
;
break
;
break
;
case
JOIN_LEFT
:
case
JOIN_LEFT
:
mergestate
->
mj_FillOuter
=
true
;
mergestate
->
mj_FillInner
=
false
;
mergestate
->
mj_NullInnerTupleSlot
=
mergestate
->
mj_NullInnerTupleSlot
=
ExecInitNullTupleSlot
(
estate
,
ExecInitNullTupleSlot
(
estate
,
ExecGetResultType
(
innerPlanState
(
mergestate
)));
ExecGetResultType
(
innerPlanState
(
mergestate
)));
break
;
break
;
case
JOIN_RIGHT
:
case
JOIN_RIGHT
:
mergestate
->
mj_FillOuter
=
false
;
mergestate
->
mj_FillInner
=
true
;
mergestate
->
mj_NullOuterTupleSlot
=
mergestate
->
mj_NullOuterTupleSlot
=
ExecInitNullTupleSlot
(
estate
,
ExecInitNullTupleSlot
(
estate
,
ExecGetResultType
(
outerPlanState
(
mergestate
)));
ExecGetResultType
(
outerPlanState
(
mergestate
)));
...
@@ -1622,6 +1563,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
...
@@ -1622,6 +1563,8 @@ ExecInitMergeJoin(MergeJoin *node, EState *estate)
errmsg
(
"RIGHT JOIN is only supported with merge-joinable join conditions"
)));
errmsg
(
"RIGHT JOIN is only supported with merge-joinable join conditions"
)));
break
;
break
;
case
JOIN_FULL
:
case
JOIN_FULL
:
mergestate
->
mj_FillOuter
=
true
;
mergestate
->
mj_FillInner
=
true
;
mergestate
->
mj_NullOuterTupleSlot
=
mergestate
->
mj_NullOuterTupleSlot
=
ExecInitNullTupleSlot
(
estate
,
ExecInitNullTupleSlot
(
estate
,
ExecGetResultType
(
outerPlanState
(
mergestate
)));
ExecGetResultType
(
outerPlanState
(
mergestate
)));
...
...
src/include/nodes/execnodes.h
View file @
fabef304
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
* 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
...
@@ -1031,6 +1031,8 @@ typedef struct NestLoopState
* NumClauses number of mergejoinable join clauses
* NumClauses number of mergejoinable join clauses
* Clauses info for each mergejoinable clause
* Clauses info for each mergejoinable clause
* JoinState current "state" of join. see execdefs.h
* 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
* MatchedOuter true if found a join match for current outer tuple
* MatchedInner true if found a join match for current inner tuple
* MatchedInner true if found a join match for current inner tuple
* OuterTupleSlot slot in tuple table for cur outer tuple
* OuterTupleSlot slot in tuple table for cur outer tuple
...
@@ -1051,6 +1053,8 @@ typedef struct MergeJoinState
...
@@ -1051,6 +1053,8 @@ typedef struct MergeJoinState
int
mj_NumClauses
;
int
mj_NumClauses
;
MergeJoinClause
mj_Clauses
;
/* array of length mj_NumClauses */
MergeJoinClause
mj_Clauses
;
/* array of length mj_NumClauses */
int
mj_JoinState
;
int
mj_JoinState
;
bool
mj_FillOuter
;
bool
mj_FillInner
;
bool
mj_MatchedOuter
;
bool
mj_MatchedOuter
;
bool
mj_MatchedInner
;
bool
mj_MatchedInner
;
TupleTableSlot
*
mj_OuterTupleSlot
;
TupleTableSlot
*
mj_OuterTupleSlot
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment