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
7fe29ece
Commit
7fe29ece
authored
Feb 22, 1999
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
comment cleanup.
parent
01ec673c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
190 additions
and
299 deletions
+190
-299
src/backend/executor/execMain.c
src/backend/executor/execMain.c
+58
-115
src/backend/executor/execQual.c
src/backend/executor/execQual.c
+52
-100
src/backend/executor/nodeMergejoin.c
src/backend/executor/nodeMergejoin.c
+80
-84
No files found.
src/backend/executor/execMain.c
View file @
7fe29ece
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.7
8 1999/02/21 03:48:36 scrappy
Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.7
9 1999/02/22 19:40:09 momjian
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -204,16 +204,14 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
...
@@ -204,16 +204,14 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
int
offset
=
0
;
int
offset
=
0
;
int
count
=
0
;
int
count
=
0
;
/*
*****************
/*
* sanity checks
* sanity checks
******************
*/
*/
Assert
(
queryDesc
!=
NULL
);
Assert
(
queryDesc
!=
NULL
);
/*
*****************
/*
* extract information from the query descriptor
* extract information from the query descriptor
* and the query feature.
* and the query feature.
******************
*/
*/
operation
=
queryDesc
->
operation
;
operation
=
queryDesc
->
operation
;
plan
=
queryDesc
->
plantree
;
plan
=
queryDesc
->
plantree
;
...
@@ -222,18 +220,16 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
...
@@ -222,18 +220,16 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
estate
->
es_processed
=
0
;
estate
->
es_processed
=
0
;
estate
->
es_lastoid
=
InvalidOid
;
estate
->
es_lastoid
=
InvalidOid
;
/*
*****************
/*
* FIXME: the dest setup function ought to be handed the tuple desc
* FIXME: the dest setup function ought to be handed the tuple desc
* for the tuples to be output, but I'm not quite sure how to get that
* for the tuples to be output, but I'm not quite sure how to get that
* info at this point. For now, passing NULL is OK because no existing
* info at this point. For now, passing NULL is OK because no existing
* dest setup function actually uses the pointer.
* dest setup function actually uses the pointer.
******************
*/
*/
(
*
destfunc
->
setup
)
(
destfunc
,
(
TupleDesc
)
NULL
);
(
*
destfunc
->
setup
)
(
destfunc
,
(
TupleDesc
)
NULL
);
/*
*****************
/*
* if given get the offset of the LIMIT clause
* if given get the offset of the LIMIT clause
******************
*/
*/
if
(
limoffset
!=
NULL
)
if
(
limoffset
!=
NULL
)
{
{
...
@@ -276,9 +272,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
...
@@ -276,9 +272,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
elog
(
ERROR
,
"limit offset cannot be negative"
);
elog
(
ERROR
,
"limit offset cannot be negative"
);
}
}
/*
*****************
/*
* if given get the count of the LIMIT clause
* if given get the count of the LIMIT clause
******************
*/
*/
if
(
limcount
!=
NULL
)
if
(
limcount
!=
NULL
)
{
{
...
@@ -343,9 +338,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
...
@@ -343,9 +338,8 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
destfunc
);
destfunc
);
break
;
break
;
/*
*****************
/*
* retrieve next n "backward" tuples
* retrieve next n "backward" tuples
******************
*/
*/
case
EXEC_BACK
:
case
EXEC_BACK
:
result
=
ExecutePlan
(
estate
,
result
=
ExecutePlan
(
estate
,
...
@@ -357,10 +351,9 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
...
@@ -357,10 +351,9 @@ ExecutorRun(QueryDesc *queryDesc, EState *estate, int feature,
destfunc
);
destfunc
);
break
;
break
;
/*
*****************
/*
* return one tuple but don't "retrieve" it.
* return one tuple but don't "retrieve" it.
* (this is used by the rule manager..) -cim 9/14/89
* (this is used by the rule manager..) -cim 9/14/89
******************
*/
*/
case
EXEC_RETONE
:
case
EXEC_RETONE
:
result
=
ExecutePlan
(
estate
,
result
=
ExecutePlan
(
estate
,
...
@@ -561,9 +554,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -561,9 +554,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
List
*
targetList
;
List
*
targetList
;
int
len
;
int
len
;
/*
*****************
/*
* get information from query descriptor
* get information from query descriptor
******************
*/
*/
rangeTable
=
parseTree
->
rtable
;
rangeTable
=
parseTree
->
rtable
;
resultRelation
=
parseTree
->
resultRelation
;
resultRelation
=
parseTree
->
resultRelation
;
...
@@ -572,32 +564,28 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -572,32 +564,28 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
ExecCheckPerms
(
operation
,
resultRelation
,
rangeTable
,
parseTree
);
ExecCheckPerms
(
operation
,
resultRelation
,
rangeTable
,
parseTree
);
#endif
#endif
/*
*****************
/*
* initialize the node's execution state
* initialize the node's execution state
******************
*/
*/
estate
->
es_range_table
=
rangeTable
;
estate
->
es_range_table
=
rangeTable
;
/*
*****************
/*
* initialize the BaseId counter so node base_id's
* initialize the BaseId counter so node base_id's
* are assigned correctly. Someday baseid's will have to
* are assigned correctly. Someday baseid's will have to
* be stored someplace other than estate because they
* be stored someplace other than estate because they
* should be unique per query planned.
* should be unique per query planned.
******************
*/
*/
estate
->
es_BaseId
=
1
;
estate
->
es_BaseId
=
1
;
/*
*****************
/*
* initialize result relation stuff
* initialize result relation stuff
******************
*/
*/
if
(
resultRelation
!=
0
&&
operation
!=
CMD_SELECT
)
if
(
resultRelation
!=
0
&&
operation
!=
CMD_SELECT
)
{
{
/*
*****************
/*
* if we have a result relation, open it and
* if we have a result relation, open it and
* initialize the result relation info stuff.
* initialize the result relation info stuff.
******************
*/
*/
RelationInfo
*
resultRelationInfo
;
RelationInfo
*
resultRelationInfo
;
Index
resultRelationIndex
;
Index
resultRelationIndex
;
...
@@ -623,10 +611,9 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -623,10 +611,9 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
resultRelationInfo
->
ri_IndexRelationDescs
=
NULL
;
resultRelationInfo
->
ri_IndexRelationDescs
=
NULL
;
resultRelationInfo
->
ri_IndexRelationInfo
=
NULL
;
resultRelationInfo
->
ri_IndexRelationInfo
=
NULL
;
/*
*****************
/*
* open indices on result relation and save descriptors
* open indices on result relation and save descriptors
* in the result relation information..
* in the result relation information..
******************
*/
*/
if
(
operation
!=
CMD_DELETE
)
if
(
operation
!=
CMD_DELETE
)
ExecOpenIndices
(
resultRelationOid
,
resultRelationInfo
);
ExecOpenIndices
(
resultRelationOid
,
resultRelationInfo
);
...
@@ -635,9 +622,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -635,9 +622,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
}
}
else
else
{
{
/*
*****************
/*
* if no result relation, then set state appropriately
* if no result relation, then set state appropriately
******************
*/
*/
estate
->
es_result_relation_info
=
NULL
;
estate
->
es_result_relation_info
=
NULL
;
}
}
...
@@ -670,9 +656,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -670,9 +656,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
}
}
}
}
/*
*****************
/*
* initialize the executor "tuple" table.
* initialize the executor "tuple" table.
******************
*/
*/
{
{
int
nSlots
=
ExecCountSlotsNode
(
plan
);
int
nSlots
=
ExecCountSlotsNode
(
plan
);
...
@@ -681,33 +666,30 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -681,33 +666,30 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
estate
->
es_tupleTable
=
tupleTable
;
estate
->
es_tupleTable
=
tupleTable
;
}
}
/*
*****************
/*
* initialize the private state information for
* initialize the private state information for
* all the nodes in the query tree. This opens
* all the nodes in the query tree. This opens
* files, allocates storage and leaves us ready
* files, allocates storage and leaves us ready
* to start processing tuples..
* to start processing tuples..
******************
*/
*/
ExecInitNode
(
plan
,
estate
,
NULL
);
ExecInitNode
(
plan
,
estate
,
NULL
);
/*
*****************
/*
* get the tuple descriptor describing the type
* get the tuple descriptor describing the type
* of tuples to return.. (this is especially important
* of tuples to return.. (this is especially important
* if we are creating a relation with "retrieve into")
* if we are creating a relation with "retrieve into")
******************
*/
*/
tupType
=
ExecGetTupType
(
plan
);
/* tuple descriptor */
tupType
=
ExecGetTupType
(
plan
);
/* tuple descriptor */
targetList
=
plan
->
targetlist
;
targetList
=
plan
->
targetlist
;
len
=
ExecTargetListLength
(
targetList
);
/* number of attributes */
len
=
ExecTargetListLength
(
targetList
);
/* number of attributes */
/*
*****************
/*
* now that we have the target list, initialize the junk filter
* now that we have the target list, initialize the junk filter
* if this is a REPLACE or a DELETE query.
* if this is a REPLACE or a DELETE query.
* We also init the junk filter if this is an append query
* We also init the junk filter if this is an append query
* (there might be some rule lock info there...)
* (there might be some rule lock info there...)
* NOTE: in the future we might want to initialize the junk
* NOTE: in the future we might want to initialize the junk
* filter for all queries.
* filter for all queries.
******************
* SELECT added by daveh@insightdist.com 5/20/98 to allow
* SELECT added by daveh@insightdist.com 5/20/98 to allow
* ORDER/GROUP BY have an identifier missing from the target.
* ORDER/GROUP BY have an identifier missing from the target.
*/
*/
...
@@ -744,9 +726,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -744,9 +726,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
estate
->
es_junkFilter
=
NULL
;
estate
->
es_junkFilter
=
NULL
;
}
}
/*
*****************
/*
* initialize the "into" relation
* initialize the "into" relation
******************
*/
*/
intoRelationDesc
=
(
Relation
)
NULL
;
intoRelationDesc
=
(
Relation
)
NULL
;
...
@@ -764,9 +745,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -764,9 +745,8 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
*/
*/
if
(
parseTree
->
into
!=
NULL
)
if
(
parseTree
->
into
!=
NULL
)
{
{
/*
*****************
/*
* create the "into" relation
* create the "into" relation
******************
*/
*/
intoName
=
parseTree
->
into
;
intoName
=
parseTree
->
into
;
...
@@ -780,11 +760,10 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
...
@@ -780,11 +760,10 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
FreeTupleDesc
(
tupdesc
);
FreeTupleDesc
(
tupdesc
);
/*
*****************
/*
* XXX rather than having to call setheapoverride(true)
* XXX rather than having to call setheapoverride(true)
* and then back to false, we should change the
* and then back to false, we should change the
* arguments to heap_open() instead..
* arguments to heap_open() instead..
******************
*/
*/
setheapoverride
(
true
);
setheapoverride
(
true
);
...
@@ -817,22 +796,19 @@ EndPlan(Plan *plan, EState *estate)
...
@@ -817,22 +796,19 @@ EndPlan(Plan *plan, EState *estate)
RelationInfo
*
resultRelationInfo
;
RelationInfo
*
resultRelationInfo
;
Relation
intoRelationDesc
;
Relation
intoRelationDesc
;
/*
*****************
/*
* get information from state
* get information from state
******************
*/
*/
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationInfo
=
estate
->
es_result_relation_info
;
intoRelationDesc
=
estate
->
es_into_relation_descriptor
;
intoRelationDesc
=
estate
->
es_into_relation_descriptor
;
/*
*****************
/*
* shut down the query
* shut down the query
******************
*/
*/
ExecEndNode
(
plan
,
plan
);
ExecEndNode
(
plan
,
plan
);
/*
*****************
/*
* destroy the executor "tuple" table.
* destroy the executor "tuple" table.
******************
*/
*/
{
{
TupleTable
tupleTable
=
(
TupleTable
)
estate
->
es_tupleTable
;
TupleTable
tupleTable
=
(
TupleTable
)
estate
->
es_tupleTable
;
...
@@ -841,9 +817,8 @@ EndPlan(Plan *plan, EState *estate)
...
@@ -841,9 +817,8 @@ EndPlan(Plan *plan, EState *estate)
estate
->
es_tupleTable
=
NULL
;
estate
->
es_tupleTable
=
NULL
;
}
}
/*
*****************
/*
* close the result relations if necessary
* close the result relations if necessary
******************
*/
*/
if
(
resultRelationInfo
!=
NULL
)
if
(
resultRelationInfo
!=
NULL
)
{
{
...
@@ -852,16 +827,14 @@ EndPlan(Plan *plan, EState *estate)
...
@@ -852,16 +827,14 @@ EndPlan(Plan *plan, EState *estate)
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
heap_close
(
resultRelationDesc
);
heap_close
(
resultRelationDesc
);
/*
*****************
/*
* close indices on the result relation
* close indices on the result relation
******************
*/
*/
ExecCloseIndices
(
resultRelationInfo
);
ExecCloseIndices
(
resultRelationInfo
);
}
}
/*
*****************
/*
* close the "into" relation if necessary
* close the "into" relation if necessary
******************
*/
*/
if
(
intoRelationDesc
!=
NULL
)
if
(
intoRelationDesc
!=
NULL
)
heap_close
(
intoRelationDesc
);
heap_close
(
intoRelationDesc
);
...
@@ -900,31 +873,27 @@ ExecutePlan(EState *estate,
...
@@ -900,31 +873,27 @@ ExecutePlan(EState *estate,
int
current_tuple_count
;
int
current_tuple_count
;
TupleTableSlot
*
result
;
TupleTableSlot
*
result
;
/*
*****************
/*
* initialize local variables
* initialize local variables
******************
*/
*/
slot
=
NULL
;
slot
=
NULL
;
current_tuple_count
=
0
;
current_tuple_count
=
0
;
result
=
NULL
;
result
=
NULL
;
/*
*****************
/*
* Set the direction.
* Set the direction.
******************
*/
*/
estate
->
es_direction
=
direction
;
estate
->
es_direction
=
direction
;
/*
*****************
/*
* Loop until we've processed the proper number
* Loop until we've processed the proper number
* of tuples from the plan..
* of tuples from the plan..
******************
*/
*/
for
(;;)
for
(;;)
{
{
/*
*****************
/*
* Execute the plan and obtain a tuple
* Execute the plan and obtain a tuple
******************
*/
*/
/* at the top level, the parent of a plan (2nd arg) is itself */
/* at the top level, the parent of a plan (2nd arg) is itself */
lnext:
;
lnext:
;
...
@@ -937,11 +906,10 @@ lnext:;
...
@@ -937,11 +906,10 @@ lnext:;
else
else
slot
=
ExecProcNode
(
plan
,
plan
);
slot
=
ExecProcNode
(
plan
,
plan
);
/*
*****************
/*
* if the tuple is null, then we assume
* if the tuple is null, then we assume
* there is nothing more to process so
* there is nothing more to process so
* we just return null...
* we just return null...
******************
*/
*/
if
(
TupIsNull
(
slot
))
if
(
TupIsNull
(
slot
))
{
{
...
@@ -949,13 +917,12 @@ lnext:;
...
@@ -949,13 +917,12 @@ lnext:;
break
;
break
;
}
}
/*
*****************
/*
* For now we completely execute the plan and skip
* For now we completely execute the plan and skip
* result tuples if requested by LIMIT offset.
* result tuples if requested by LIMIT offset.
* Finally we should try to do it in deeper levels
* Finally we should try to do it in deeper levels
* if possible (during index scan)
* if possible (during index scan)
* - Jan
* - Jan
******************
*/
*/
if
(
offsetTuples
>
0
)
if
(
offsetTuples
>
0
)
{
{
...
@@ -963,7 +930,7 @@ lnext:;
...
@@ -963,7 +930,7 @@ lnext:;
continue
;
continue
;
}
}
/*
*****************
/*
* if we have a junk filter, then project a new
* if we have a junk filter, then project a new
* tuple with the junk removed.
* tuple with the junk removed.
*
*
...
@@ -971,7 +938,6 @@ lnext:;
...
@@ -971,7 +938,6 @@ lnext:;
* original tuple.
* original tuple.
*
*
* Also, extract all the junk information we need.
* Also, extract all the junk information we need.
******************
*/
*/
if
((
junkfilter
=
estate
->
es_junkFilter
)
!=
(
JunkFilter
*
)
NULL
)
if
((
junkfilter
=
estate
->
es_junkFilter
)
!=
(
JunkFilter
*
)
NULL
)
{
{
...
@@ -979,9 +945,8 @@ lnext:;
...
@@ -979,9 +945,8 @@ lnext:;
HeapTuple
newTuple
;
HeapTuple
newTuple
;
bool
isNull
;
bool
isNull
;
/*
*****************
/*
* extract the 'ctid' junk attribute.
* extract the 'ctid' junk attribute.
******************
*/
*/
if
(
operation
==
CMD_UPDATE
||
operation
==
CMD_DELETE
)
if
(
operation
==
CMD_UPDATE
||
operation
==
CMD_DELETE
)
{
{
...
@@ -1063,10 +1028,9 @@ lmark:;
...
@@ -1063,10 +1028,9 @@ lmark:;
}
}
}
}
/*
*****************
/*
* Finally create a new "clean" tuple with all junk attributes
* Finally create a new "clean" tuple with all junk attributes
* removed
* removed
******************
*/
*/
newTuple
=
ExecRemoveJunk
(
junkfilter
,
slot
);
newTuple
=
ExecRemoveJunk
(
junkfilter
,
slot
);
...
@@ -1077,12 +1041,11 @@ lmark:;
...
@@ -1077,12 +1041,11 @@ lmark:;
true
);
/* tuple should be pfreed */
true
);
/* tuple should be pfreed */
}
/* if (junkfilter... */
}
/* if (junkfilter... */
/*
*****************
/*
* now that we have a tuple, do the appropriate thing
* now that we have a tuple, do the appropriate thing
* with it.. either return it to the user, add
* with it.. either return it to the user, add
* it to a relation someplace, delete it from a
* it to a relation someplace, delete it from a
* relation, or modify some of it's attributes.
* relation, or modify some of it's attributes.
******************
*/
*/
switch
(
operation
)
switch
(
operation
)
...
@@ -1114,21 +1077,19 @@ lmark:;
...
@@ -1114,21 +1077,19 @@ lmark:;
result
=
NULL
;
result
=
NULL
;
break
;
break
;
}
}
/*
*****************
/*
* check our tuple count.. if we've returned the
* check our tuple count.. if we've returned the
* proper number then return, else loop again and
* proper number then return, else loop again and
* process more tuples..
* process more tuples..
******************
*/
*/
current_tuple_count
+=
1
;
current_tuple_count
+=
1
;
if
(
numberTuples
==
current_tuple_count
)
if
(
numberTuples
==
current_tuple_count
)
break
;
break
;
}
}
/*
*****************
/*
* here, result is either a slot containing a tuple in the case
* here, result is either a slot containing a tuple in the case
* of a RETRIEVE or NULL otherwise.
* of a RETRIEVE or NULL otherwise.
******************
*/
*/
return
result
;
return
result
;
}
}
...
@@ -1151,16 +1112,14 @@ ExecRetrieve(TupleTableSlot *slot,
...
@@ -1151,16 +1112,14 @@ ExecRetrieve(TupleTableSlot *slot,
HeapTuple
tuple
;
HeapTuple
tuple
;
TupleDesc
attrtype
;
TupleDesc
attrtype
;
/*
*****************
/*
* get the heap tuple out of the tuple table slot
* get the heap tuple out of the tuple table slot
******************
*/
*/
tuple
=
slot
->
val
;
tuple
=
slot
->
val
;
attrtype
=
slot
->
ttc_tupleDescriptor
;
attrtype
=
slot
->
ttc_tupleDescriptor
;
/*
*****************
/*
* insert the tuple into the "into relation"
* insert the tuple into the "into relation"
******************
*/
*/
if
(
estate
->
es_into_relation_descriptor
!=
NULL
)
if
(
estate
->
es_into_relation_descriptor
!=
NULL
)
{
{
...
@@ -1168,9 +1127,8 @@ ExecRetrieve(TupleTableSlot *slot,
...
@@ -1168,9 +1127,8 @@ ExecRetrieve(TupleTableSlot *slot,
IncrAppended
();
IncrAppended
();
}
}
/*
*****************
/*
* send the tuple to the front end (or the screen)
* send the tuple to the front end (or the screen)
******************
*/
*/
(
*
destfunc
->
receiveTuple
)
(
tuple
,
attrtype
,
destfunc
);
(
*
destfunc
->
receiveTuple
)
(
tuple
,
attrtype
,
destfunc
);
IncrRetrieved
();
IncrRetrieved
();
...
@@ -1197,23 +1155,20 @@ ExecAppend(TupleTableSlot *slot,
...
@@ -1197,23 +1155,20 @@ ExecAppend(TupleTableSlot *slot,
int
numIndices
;
int
numIndices
;
Oid
newId
;
Oid
newId
;
/*
*****************
/*
* get the heap tuple out of the tuple table slot
* get the heap tuple out of the tuple table slot
******************
*/
*/
tuple
=
slot
->
val
;
tuple
=
slot
->
val
;
/*
*****************
/*
* get information on the result relation
* get information on the result relation
******************
*/
*/
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
/*
*****************
/*
* have to add code to preform unique checking here.
* have to add code to preform unique checking here.
* cim -12/1/89
* cim -12/1/89
******************
*/
*/
/* BEFORE ROW INSERT Triggers */
/* BEFORE ROW INSERT Triggers */
...
@@ -1235,9 +1190,8 @@ ExecAppend(TupleTableSlot *slot,
...
@@ -1235,9 +1190,8 @@ ExecAppend(TupleTableSlot *slot,
}
}
}
}
/*
*****************
/*
* Check the constraints of a tuple
* Check the constraints of a tuple
******************
*/
*/
if
(
resultRelationDesc
->
rd_att
->
constr
)
if
(
resultRelationDesc
->
rd_att
->
constr
)
...
@@ -1245,21 +1199,19 @@ ExecAppend(TupleTableSlot *slot,
...
@@ -1245,21 +1199,19 @@ ExecAppend(TupleTableSlot *slot,
ExecConstraints
(
"ExecAppend"
,
resultRelationDesc
,
tuple
,
estate
);
ExecConstraints
(
"ExecAppend"
,
resultRelationDesc
,
tuple
,
estate
);
}
}
/*
*****************
/*
* insert the tuple
* insert the tuple
******************
*/
*/
newId
=
heap_insert
(
resultRelationDesc
,
/* relation desc */
newId
=
heap_insert
(
resultRelationDesc
,
/* relation desc */
tuple
);
/* heap tuple */
tuple
);
/* heap tuple */
IncrAppended
();
IncrAppended
();
/*
*****************
/*
* process indices
* process indices
*
*
* Note: heap_insert adds a new tuple to a relation. As a side
* Note: heap_insert adds a new tuple to a relation. As a side
* effect, the tupleid of the new tuple is placed in the new
* effect, the tupleid of the new tuple is placed in the new
* tuple's t_ctid field.
* tuple's t_ctid field.
******************
*/
*/
numIndices
=
resultRelationInfo
->
ri_NumIndices
;
numIndices
=
resultRelationInfo
->
ri_NumIndices
;
if
(
numIndices
>
0
)
if
(
numIndices
>
0
)
...
@@ -1290,9 +1242,8 @@ ExecDelete(TupleTableSlot *slot,
...
@@ -1290,9 +1242,8 @@ ExecDelete(TupleTableSlot *slot,
ItemPointerData
ctid
;
ItemPointerData
ctid
;
int
result
;
int
result
;
/*
*****************
/*
* get the result relation information
* get the result relation information
******************
*/
*/
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
...
@@ -1346,7 +1297,7 @@ ldelete:;
...
@@ -1346,7 +1297,7 @@ ldelete:;
IncrDeleted
();
IncrDeleted
();
(
estate
->
es_processed
)
++
;
(
estate
->
es_processed
)
++
;
/*
*****************
/*
* Note: Normally one would think that we have to
* Note: Normally one would think that we have to
* delete index tuples associated with the
* delete index tuples associated with the
* heap tuple now..
* heap tuple now..
...
@@ -1355,7 +1306,6 @@ ldelete:;
...
@@ -1355,7 +1306,6 @@ ldelete:;
* because the vacuum daemon automatically
* because the vacuum daemon automatically
* opens an index scan and deletes index tuples
* opens an index scan and deletes index tuples
* when it finds deleted heap tuples. -cim 9/27/89
* when it finds deleted heap tuples. -cim 9/27/89
******************
*/
*/
/* AFTER ROW DELETE Triggers */
/* AFTER ROW DELETE Triggers */
...
@@ -1388,9 +1338,8 @@ ExecReplace(TupleTableSlot *slot,
...
@@ -1388,9 +1338,8 @@ ExecReplace(TupleTableSlot *slot,
int
result
;
int
result
;
int
numIndices
;
int
numIndices
;
/*
*****************
/*
* abort the operation if not running transactions
* abort the operation if not running transactions
******************
*/
*/
if
(
IsBootstrapProcessingMode
())
if
(
IsBootstrapProcessingMode
())
{
{
...
@@ -1398,25 +1347,22 @@ ExecReplace(TupleTableSlot *slot,
...
@@ -1398,25 +1347,22 @@ ExecReplace(TupleTableSlot *slot,
return
;
return
;
}
}
/*
*****************
/*
* get the heap tuple out of the tuple table slot
* get the heap tuple out of the tuple table slot
******************
*/
*/
tuple
=
slot
->
val
;
tuple
=
slot
->
val
;
/*
*****************
/*
* get the result relation information
* get the result relation information
******************
*/
*/
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationInfo
=
estate
->
es_result_relation_info
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
resultRelationDesc
=
resultRelationInfo
->
ri_RelationDesc
;
/*
*****************
/*
* have to add code to preform unique checking here.
* have to add code to preform unique checking here.
* in the event of unique tuples, this becomes a deletion
* in the event of unique tuples, this becomes a deletion
* of the original tuple affected by the replace.
* of the original tuple affected by the replace.
* cim -12/1/89
* cim -12/1/89
******************
*/
*/
/* BEFORE ROW UPDATE Triggers */
/* BEFORE ROW UPDATE Triggers */
...
@@ -1438,9 +1384,8 @@ ExecReplace(TupleTableSlot *slot,
...
@@ -1438,9 +1384,8 @@ ExecReplace(TupleTableSlot *slot,
}
}
}
}
/*
*****************
/*
* Check the constraints of a tuple
* Check the constraints of a tuple
******************
*/
*/
if
(
resultRelationDesc
->
rd_att
->
constr
)
if
(
resultRelationDesc
->
rd_att
->
constr
)
...
@@ -1487,7 +1432,7 @@ lreplace:;
...
@@ -1487,7 +1432,7 @@ lreplace:;
IncrReplaced
();
IncrReplaced
();
(
estate
->
es_processed
)
++
;
(
estate
->
es_processed
)
++
;
/*
*****************
/*
* Note: instead of having to update the old index tuples
* Note: instead of having to update the old index tuples
* associated with the heap tuple, all we do is form
* associated with the heap tuple, all we do is form
* and insert new index tuples.. This is because
* and insert new index tuples.. This is because
...
@@ -1495,10 +1440,9 @@ lreplace:;
...
@@ -1495,10 +1440,9 @@ lreplace:;
* index tuple deletion is done automagically by
* index tuple deletion is done automagically by
* the vaccuum deamon.. All we do is insert new
* the vaccuum deamon.. All we do is insert new
* index tuples. -cim 9/27/89
* index tuples. -cim 9/27/89
******************
*/
*/
/*
*****************
/*
* process indices
* process indices
*
*
* heap_replace updates a tuple in the base relation by invalidating
* heap_replace updates a tuple in the base relation by invalidating
...
@@ -1506,7 +1450,6 @@ lreplace:;
...
@@ -1506,7 +1450,6 @@ lreplace:;
* effect, the tupleid of the new tuple is placed in the new
* effect, the tupleid of the new tuple is placed in the new
* tuple's t_ctid field. So we now insert index tuples using
* tuple's t_ctid field. So we now insert index tuples using
* the new tupleid stored there.
* the new tupleid stored there.
******************
*/
*/
numIndices
=
resultRelationInfo
->
ri_NumIndices
;
numIndices
=
resultRelationInfo
->
ri_NumIndices
;
...
...
src/backend/executor/execQual.c
View file @
7fe29ece
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.4
4 1999/02/21 03:48:39 scrappy
Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.4
5 1999/02/22 19:40:09 momjian
Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -53,9 +53,8 @@
...
@@ -53,9 +53,8 @@
#include "utils/memutils.h"
#include "utils/memutils.h"
/*
*****************
/*
* externs and constants
* externs and constants
******************
*/
*/
/*
/*
...
@@ -84,14 +83,13 @@ static Datum ExecMakeFunctionResult(Node *node, List *arguments,
...
@@ -84,14 +83,13 @@ static Datum ExecMakeFunctionResult(Node *node, List *arguments,
ExprContext
*
econtext
,
bool
*
isNull
,
bool
*
isDone
);
ExprContext
*
econtext
,
bool
*
isNull
,
bool
*
isDone
);
static
bool
ExecQualClause
(
Node
*
clause
,
ExprContext
*
econtext
);
static
bool
ExecQualClause
(
Node
*
clause
,
ExprContext
*
econtext
);
/*
*****************
/*
* ExecEvalArrayRef
* ExecEvalArrayRef
*
*
* This function takes an ArrayRef and returns a Const Node if it
* This function takes an ArrayRef and returns a Const Node if it
* is an array reference or returns the changed Array Node if it is
* is an array reference or returns the changed Array Node if it is
* an array assignment.
* an array assignment.
*
*/
******************/
static
Datum
static
Datum
ExecEvalArrayRef
(
ArrayRef
*
arrayRef
,
ExecEvalArrayRef
(
ArrayRef
*
arrayRef
,
ExprContext
*
econtext
,
ExprContext
*
econtext
,
...
@@ -233,9 +231,8 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
...
@@ -233,9 +231,8 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
bool
byval
;
bool
byval
;
int16
len
;
int16
len
;
/*
*****************
/*
* get the slot we want
* get the slot we want
******************
*/
*/
switch
(
variable
->
varno
)
switch
(
variable
->
varno
)
{
{
...
@@ -253,9 +250,8 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
...
@@ -253,9 +250,8 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
break
;
break
;
}
}
/*
*****************
/*
* extract tuple information from the slot
* extract tuple information from the slot
******************
*/
*/
heapTuple
=
slot
->
val
;
heapTuple
=
slot
->
val
;
tuple_type
=
slot
->
ttc_tupleDescriptor
;
tuple_type
=
slot
->
ttc_tupleDescriptor
;
...
@@ -302,14 +298,13 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
...
@@ -302,14 +298,13 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
tuple_type
,
/* tuple descriptor of tuple */
tuple_type
,
/* tuple descriptor of tuple */
isNull
);
/* return: is attribute null? */
isNull
);
/* return: is attribute null? */
/*
*****************
/*
* return null if att is null
* return null if att is null
******************
*/
*/
if
(
*
isNull
)
if
(
*
isNull
)
return
(
Datum
)
NULL
;
return
(
Datum
)
NULL
;
/*
*****************
/*
* get length and type information..
* get length and type information..
* ??? what should we do about variable length attributes
* ??? what should we do about variable length attributes
* - variable length attributes have their length stored
* - variable length attributes have their length stored
...
@@ -317,15 +312,13 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
...
@@ -317,15 +312,13 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
* returned value.. If we can determine that the type
* returned value.. If we can determine that the type
* is a variable length type, we can do the right thing.
* is a variable length type, we can do the right thing.
* -cim 9/15/89
* -cim 9/15/89
******************
*/
*/
if
(
attnum
<
0
)
if
(
attnum
<
0
)
{
{
/*
*****************
/*
* If this is a pseudo-att, we get the type and fake the length.
* If this is a pseudo-att, we get the type and fake the length.
* There ought to be a routine to return the real lengths, so
* There ought to be a routine to return the real lengths, so
* we'll mark this one ... XXX -mao
* we'll mark this one ... XXX -mao
******************
*/
*/
len
=
heap_sysattrlen
(
attnum
);
/* XXX see -mao above */
len
=
heap_sysattrlen
(
attnum
);
/* XXX see -mao above */
byval
=
heap_sysattrbyval
(
attnum
);
/* XXX see -mao above */
byval
=
heap_sysattrbyval
(
attnum
);
/* XXX see -mao above */
...
@@ -490,7 +483,7 @@ ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
...
@@ -490,7 +483,7 @@ ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
* ----------------------------------------------------------------
* ----------------------------------------------------------------
*/
*/
/*
*****************
/*
* GetAttributeByName
* GetAttributeByName
* GetAttributeByNum
* GetAttributeByNum
*
*
...
@@ -498,7 +491,6 @@ ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
...
@@ -498,7 +491,6 @@ ExecEvalParam(Param *expression, ExprContext *econtext, bool *isNull)
* named attribute out of the tuple from the arg slot. User defined
* named attribute out of the tuple from the arg slot. User defined
* C functions which take a tuple as an argument are expected
* C functions which take a tuple as an argument are expected
* to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
* to use this. Ex: overpaid(EMP) might call GetAttributeByNum().
******************
*/
*/
/* static but gets called from external functions */
/* static but gets called from external functions */
char
*
char
*
...
@@ -617,12 +609,11 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
...
@@ -617,12 +609,11 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
i
=
0
;
i
=
0
;
foreach
(
arg
,
argList
)
foreach
(
arg
,
argList
)
{
{
/*
*****************
/*
* evaluate the expression, in general functions cannot take
* evaluate the expression, in general functions cannot take
* sets as arguments but we make an exception in the case of
* sets as arguments but we make an exception in the case of
* nested dot expressions. We have to watch out for this case
* nested dot expressions. We have to watch out for this case
* here.
* here.
******************
*/
*/
argV
[
i
]
=
(
Datum
)
argV
[
i
]
=
(
Datum
)
ExecEvalExpr
((
Node
*
)
lfirst
(
arg
),
ExecEvalExpr
((
Node
*
)
lfirst
(
arg
),
...
@@ -645,9 +636,8 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
...
@@ -645,9 +636,8 @@ ExecEvalFuncArgs(FunctionCachePtr fcache,
}
}
}
}
/*
*****************
/*
* ExecMakeFunctionResult
* ExecMakeFunctionResult
******************
*/
*/
static
Datum
static
Datum
ExecMakeFunctionResult
(
Node
*
node
,
ExecMakeFunctionResult
(
Node
*
node
,
...
@@ -680,12 +670,11 @@ ExecMakeFunctionResult(Node *node,
...
@@ -680,12 +670,11 @@ ExecMakeFunctionResult(Node *node,
fcache
=
operNode
->
op_fcache
;
fcache
=
operNode
->
op_fcache
;
}
}
/*
*****************
/*
* arguments is a list of expressions to evaluate
* arguments is a list of expressions to evaluate
* before passing to the function manager.
* before passing to the function manager.
* We collect the results of evaluating the expressions
* We collect the results of evaluating the expressions
* into a datum array (argV) and pass this array to arrayFmgr()
* into a datum array (argV) and pass this array to arrayFmgr()
******************
*/
*/
if
(
fcache
->
nargs
!=
0
)
if
(
fcache
->
nargs
!=
0
)
{
{
...
@@ -753,10 +742,9 @@ ExecMakeFunctionResult(Node *node,
...
@@ -753,10 +742,9 @@ ExecMakeFunctionResult(Node *node,
}
}
}
}
/*
*****************
/*
* now return the value gotten by calling the function manager,
* now return the value gotten by calling the function manager,
* passing the function the evaluated parameter values.
* passing the function the evaluated parameter values.
******************
*/
*/
if
(
fcache
->
language
==
SQLlanguageId
)
if
(
fcache
->
language
==
SQLlanguageId
)
{
{
...
@@ -854,14 +842,13 @@ ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
...
@@ -854,14 +842,13 @@ ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
FunctionCachePtr
fcache
;
FunctionCachePtr
fcache
;
bool
isDone
;
bool
isDone
;
/*
*****************
/*
* an opclause is a list (op args). (I think)
* an opclause is a list (op args). (I think)
*
*
* we extract the oid of the function associated with
* we extract the oid of the function associated with
* the op and then pass the work onto ExecMakeFunctionResult
* the op and then pass the work onto ExecMakeFunctionResult
* which evaluates the arguments and returns the result of
* which evaluates the arguments and returns the result of
* calling the function on the evaluated arguments.
* calling the function on the evaluated arguments.
******************
*/
*/
op
=
(
Oper
*
)
opClause
->
oper
;
op
=
(
Oper
*
)
opClause
->
oper
;
argList
=
opClause
->
args
;
argList
=
opClause
->
args
;
...
@@ -877,10 +864,9 @@ ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
...
@@ -877,10 +864,9 @@ ExecEvalOper(Expr *opClause, ExprContext *econtext, bool *isNull)
fcache
=
op
->
op_fcache
;
fcache
=
op
->
op_fcache
;
}
}
/*
*****************
/*
* call ExecMakeFunctionResult() with a dummy isDone that we ignore.
* call ExecMakeFunctionResult() with a dummy isDone that we ignore.
* We don't have operator whose arguments are sets.
* We don't have operator whose arguments are sets.
******************
*/
*/
return
ExecMakeFunctionResult
((
Node
*
)
op
,
argList
,
econtext
,
isNull
,
&
isDone
);
return
ExecMakeFunctionResult
((
Node
*
)
op
,
argList
,
econtext
,
isNull
,
&
isDone
);
}
}
...
@@ -900,7 +886,7 @@ ExecEvalFunc(Expr *funcClause,
...
@@ -900,7 +886,7 @@ ExecEvalFunc(Expr *funcClause,
List
*
argList
;
List
*
argList
;
FunctionCachePtr
fcache
;
FunctionCachePtr
fcache
;
/*
*****************
/*
* an funcclause is a list (func args). (I think)
* an funcclause is a list (func args). (I think)
*
*
* we extract the oid of the function associated with
* we extract the oid of the function associated with
...
@@ -909,7 +895,6 @@ ExecEvalFunc(Expr *funcClause,
...
@@ -909,7 +895,6 @@ ExecEvalFunc(Expr *funcClause,
* calling the function on the evaluated arguments.
* calling the function on the evaluated arguments.
*
*
* this is nearly identical to the ExecEvalOper code.
* this is nearly identical to the ExecEvalOper code.
******************
*/
*/
func
=
(
Func
*
)
funcClause
->
oper
;
func
=
(
Func
*
)
funcClause
->
oper
;
argList
=
funcClause
->
args
;
argList
=
funcClause
->
args
;
...
@@ -953,25 +938,22 @@ ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
...
@@ -953,25 +938,22 @@ ExecEvalNot(Expr *notclause, ExprContext *econtext, bool *isNull)
clause
=
lfirst
(
notclause
->
args
);
clause
=
lfirst
(
notclause
->
args
);
/*
*****************
/*
* We don't iterate over sets in the quals, so pass in an isDone
* We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it.
* flag, but ignore it.
******************
*/
*/
expr_value
=
ExecEvalExpr
(
clause
,
econtext
,
isNull
,
&
isDone
);
expr_value
=
ExecEvalExpr
(
clause
,
econtext
,
isNull
,
&
isDone
);
/*
*****************
/*
* if the expression evaluates to null, then we just
* if the expression evaluates to null, then we just
* cascade the null back to whoever called us.
* cascade the null back to whoever called us.
******************
*/
*/
if
(
*
isNull
)
if
(
*
isNull
)
return
expr_value
;
return
expr_value
;
/*
*****************
/*
* evaluation of 'not' is simple.. expr is false, then
* evaluation of 'not' is simple.. expr is false, then
* return 'true' and vice versa.
* return 'true' and vice versa.
******************
*/
*/
if
(
DatumGetInt32
(
expr_value
)
==
0
)
if
(
DatumGetInt32
(
expr_value
)
==
0
)
return
(
Datum
)
true
;
return
(
Datum
)
true
;
...
@@ -995,7 +977,7 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
...
@@ -995,7 +977,7 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
IsNull
=
false
;
IsNull
=
false
;
clauses
=
orExpr
->
args
;
clauses
=
orExpr
->
args
;
/*
*****************
/*
* we use three valued logic functions here...
* we use three valued logic functions here...
* we evaluate each of the clauses in turn,
* we evaluate each of the clauses in turn,
* as soon as one is true we return that
* as soon as one is true we return that
...
@@ -1005,33 +987,30 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
...
@@ -1005,33 +987,30 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
* should be false) with *isNull set to false else
* should be false) with *isNull set to false else
* if none is true and at least one clause evaluated
* if none is true and at least one clause evaluated
* to NULL we set *isNull flag to true -
* to NULL we set *isNull flag to true -
******************
*/
*/
foreach
(
clause
,
clauses
)
foreach
(
clause
,
clauses
)
{
{
/*
*****************
/*
* We don't iterate over sets in the quals, so pass in an isDone
* We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it.
* flag, but ignore it.
******************
*/
*/
const_value
=
ExecEvalExpr
((
Node
*
)
lfirst
(
clause
),
const_value
=
ExecEvalExpr
((
Node
*
)
lfirst
(
clause
),
econtext
,
econtext
,
isNull
,
isNull
,
&
isDone
);
&
isDone
);
/*
*****************
/*
* if the expression evaluates to null, then we
* if the expression evaluates to null, then we
* remember it in the local IsNull flag, if none of the
* remember it in the local IsNull flag, if none of the
* clauses are true then we need to set *isNull
* clauses are true then we need to set *isNull
* to true again.
* to true again.
******************
*/
*/
if
(
*
isNull
)
if
(
*
isNull
)
{
{
IsNull
=
*
isNull
;
IsNull
=
*
isNull
;
/*
************
/*
* Many functions don't (or can't!) check if an argument is NULL
* Many functions don't (or can't!) check if an argument is NULL
* or NOT_NULL and may return TRUE (1) with *isNull TRUE
* or NOT_NULL and may return TRUE (1) with *isNull TRUE
* (an_int4_column <> 1: int4ne returns TRUE for NULLs).
* (an_int4_column <> 1: int4ne returns TRUE for NULLs).
...
@@ -1044,13 +1023,12 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
...
@@ -1044,13 +1023,12 @@ ExecEvalOr(Expr *orExpr, ExprContext *econtext, bool *isNull)
* if isnull is TRUE then the clause failed.
* if isnull is TRUE then the clause failed.
* Note: nullvalue() & nonnullvalue() always sets isnull to FALSE for NULLs.
* Note: nullvalue() & nonnullvalue() always sets isnull to FALSE for NULLs.
* - vadim 09/22/97
* - vadim 09/22/97
*
************
/
*/
const_value
=
0
;
const_value
=
0
;
}
}
/*
*****************
/*
* if we have a true result, then we return it.
* if we have a true result, then we return it.
******************
*/
*/
if
(
DatumGetInt32
(
const_value
)
!=
0
)
if
(
DatumGetInt32
(
const_value
)
!=
0
)
return
const_value
;
return
const_value
;
...
@@ -1078,41 +1056,37 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
...
@@ -1078,41 +1056,37 @@ ExecEvalAnd(Expr *andExpr, ExprContext *econtext, bool *isNull)
clauses
=
andExpr
->
args
;
clauses
=
andExpr
->
args
;
/*
*****************
/*
* we evaluate each of the clauses in turn,
* we evaluate each of the clauses in turn,
* as soon as one is false we return that
* as soon as one is false we return that
* value. If none are false or NULL then we return
* value. If none are false or NULL then we return
* the value of the last clause evaluated, which
* the value of the last clause evaluated, which
* should be true.
* should be true.
******************
*/
*/
foreach
(
clause
,
clauses
)
foreach
(
clause
,
clauses
)
{
{
/*
*****************
/*
* We don't iterate over sets in the quals, so pass in an isDone
* We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it.
* flag, but ignore it.
******************
*/
*/
const_value
=
ExecEvalExpr
((
Node
*
)
lfirst
(
clause
),
const_value
=
ExecEvalExpr
((
Node
*
)
lfirst
(
clause
),
econtext
,
econtext
,
isNull
,
isNull
,
&
isDone
);
&
isDone
);
/*
*****************
/*
* if the expression evaluates to null, then we
* if the expression evaluates to null, then we
* remember it in IsNull, if none of the clauses after
* remember it in IsNull, if none of the clauses after
* this evaluates to false we will have to set *isNull
* this evaluates to false we will have to set *isNull
* to true again.
* to true again.
******************
*/
*/
if
(
*
isNull
)
if
(
*
isNull
)
IsNull
=
*
isNull
;
IsNull
=
*
isNull
;
/*
*****************
/*
* if we have a false result, then we return it, since the
* if we have a false result, then we return it, since the
* conjunction must be false.
* conjunction must be false.
******************
*/
*/
if
(
DatumGetInt32
(
const_value
)
==
0
)
if
(
DatumGetInt32
(
const_value
)
==
0
)
return
const_value
;
return
const_value
;
...
@@ -1142,20 +1116,18 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
...
@@ -1142,20 +1116,18 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
clauses
=
caseExpr
->
args
;
clauses
=
caseExpr
->
args
;
/*
*****************
/*
* we evaluate each of the WHEN clauses in turn,
* we evaluate each of the WHEN clauses in turn,
* as soon as one is true we return the corresponding
* as soon as one is true we return the corresponding
* result. If none are true then we return the value
* result. If none are true then we return the value
* of the default clause, or NULL.
* of the default clause, or NULL.
******************
*/
*/
foreach
(
clause
,
clauses
)
foreach
(
clause
,
clauses
)
{
{
/*
*****************
/*
* We don't iterate over sets in the quals, so pass in an isDone
* We don't iterate over sets in the quals, so pass in an isDone
* flag, but ignore it.
* flag, but ignore it.
******************
*/
*/
wclause
=
lfirst
(
clause
);
wclause
=
lfirst
(
clause
);
...
@@ -1164,10 +1136,9 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
...
@@ -1164,10 +1136,9 @@ ExecEvalCase(CaseExpr *caseExpr, ExprContext *econtext, bool *isNull)
isNull
,
isNull
,
&
isDone
);
&
isDone
);
/*
*****************
/*
* if we have a true test, then we return the result,
* if we have a true test, then we return the result,
* since the case statement is satisfied.
* since the case statement is satisfied.
******************
*/
*/
if
(
DatumGetInt32
(
const_value
)
!=
0
)
if
(
DatumGetInt32
(
const_value
)
!=
0
)
{
{
...
@@ -1232,10 +1203,9 @@ ExecEvalExpr(Node *expression,
...
@@ -1232,10 +1203,9 @@ ExecEvalExpr(Node *expression,
if
(
isDone
)
if
(
isDone
)
*
isDone
=
true
;
*
isDone
=
true
;
/*
*****************
/*
* here we dispatch the work to the appropriate type
* here we dispatch the work to the appropriate type
* of function given the type of our expression.
* of function given the type of our expression.
******************
*/
*/
if
(
expression
==
NULL
)
if
(
expression
==
NULL
)
{
{
...
@@ -1354,19 +1324,17 @@ ExecQualClause(Node *clause, ExprContext *econtext)
...
@@ -1354,19 +1324,17 @@ ExecQualClause(Node *clause, ExprContext *econtext)
expr_value
=
(
Datum
)
expr_value
=
(
Datum
)
ExecEvalExpr
(
clause
,
econtext
,
&
isNull
,
&
isDone
);
ExecEvalExpr
(
clause
,
econtext
,
&
isNull
,
&
isDone
);
/*
*****************
/*
* this is interesting behaviour here. When a clause evaluates
* this is interesting behaviour here. When a clause evaluates
* to null, then we consider this as passing the qualification.
* to null, then we consider this as passing the qualification.
* it seems kind of like, if the qual is NULL, then there's no
* it seems kind of like, if the qual is NULL, then there's no
* qual..
* qual..
******************
*/
*/
if
(
isNull
)
if
(
isNull
)
return
true
;
return
true
;
/*
*****************
/*
* remember, we return true when the qualification fails..
* remember, we return true when the qualification fails..
******************
*/
*/
if
(
DatumGetInt32
(
expr_value
)
==
0
)
if
(
DatumGetInt32
(
expr_value
)
==
0
)
return
true
;
return
true
;
...
@@ -1387,9 +1355,8 @@ ExecQual(List *qual, ExprContext *econtext)
...
@@ -1387,9 +1355,8 @@ ExecQual(List *qual, ExprContext *econtext)
List
*
clause
;
List
*
clause
;
bool
result
;
bool
result
;
/*
*****************
/*
* debugging stuff
* debugging stuff
******************
*/
*/
EV_printf
(
"ExecQual: qual is "
);
EV_printf
(
"ExecQual: qual is "
);
EV_nodeDisplay
(
qual
);
EV_nodeDisplay
(
qual
);
...
@@ -1397,21 +1364,19 @@ ExecQual(List *qual, ExprContext *econtext)
...
@@ -1397,21 +1364,19 @@ ExecQual(List *qual, ExprContext *econtext)
IncrProcessed
();
IncrProcessed
();
/*
*****************
/*
* return true immediately if no qual
* return true immediately if no qual
******************
*/
*/
if
(
qual
==
NIL
)
if
(
qual
==
NIL
)
return
true
;
return
true
;
/*
*****************
/*
* a "qual" is a list of clauses. To evaluate the
* a "qual" is a list of clauses. To evaluate the
* qual, we evaluate each of the clauses in the list.
* qual, we evaluate each of the clauses in the list.
*
*
* ExecQualClause returns true when we know the qualification
* ExecQualClause returns true when we know the qualification
* *failed* so we just pass each clause in qual to it until
* *failed* so we just pass each clause in qual to it until
* we know the qual failed or there are no more clauses.
* we know the qual failed or there are no more clauses.
******************
*/
*/
result
=
false
;
result
=
false
;
...
@@ -1422,11 +1387,10 @@ ExecQual(List *qual, ExprContext *econtext)
...
@@ -1422,11 +1387,10 @@ ExecQual(List *qual, ExprContext *econtext)
break
;
break
;
}
}
/*
*****************
/*
* if result is true, then it means a clause failed so we
* if result is true, then it means a clause failed so we
* return false. if result is false then it means no clause
* return false. if result is false then it means no clause
* failed so we return true.
* failed so we return true.
******************
*/
*/
if
(
result
==
true
)
if
(
result
==
true
)
return
false
;
return
false
;
...
@@ -1482,23 +1446,21 @@ ExecTargetList(List *targetlist,
...
@@ -1482,23 +1446,21 @@ ExecTargetList(List *targetlist,
HeapTuple
newTuple
;
HeapTuple
newTuple
;
bool
isNull
;
bool
isNull
;
/*
*****************
/*
* debugging stuff
* debugging stuff
******************
*/
*/
EV_printf
(
"ExecTargetList: tl is "
);
EV_printf
(
"ExecTargetList: tl is "
);
EV_nodeDisplay
(
targetlist
);
EV_nodeDisplay
(
targetlist
);
EV_printf
(
"
\n
"
);
EV_printf
(
"
\n
"
);
/*
*****************
/*
* Return a dummy tuple if the targetlist is empty .
* Return a dummy tuple if the targetlist is empty .
* the dummy tuple is necessary to differentiate
* the dummy tuple is necessary to differentiate
* between passing and failing the qualification.
* between passing and failing the qualification.
******************
*/
*/
if
(
targetlist
==
NIL
)
if
(
targetlist
==
NIL
)
{
{
/*
*****************
/*
* I now think that the only time this makes
* I now think that the only time this makes
* any sence is when we run a delete query. Then
* any sence is when we run a delete query. Then
* we need to return something other than nil
* we need to return something other than nil
...
@@ -1512,18 +1474,16 @@ ExecTargetList(List *targetlist,
...
@@ -1512,18 +1474,16 @@ ExecTargetList(List *targetlist,
* is this a new phenomenon? it might cause bogus behavior
* is this a new phenomenon? it might cause bogus behavior
* if we try to free this tuple later!! I put a hook in
* if we try to free this tuple later!! I put a hook in
* ExecProject to watch out for this case -mer 24 Aug 1992
* ExecProject to watch out for this case -mer 24 Aug 1992
******************
*/
*/
CXT1_printf
(
"ExecTargetList: context is %d
\n
"
,
CurrentMemoryContext
);
CXT1_printf
(
"ExecTargetList: context is %d
\n
"
,
CurrentMemoryContext
);
*
isDone
=
true
;
*
isDone
=
true
;
return
(
HeapTuple
)
true
;
return
(
HeapTuple
)
true
;
}
}
/*
*****************
/*
* allocate an array of char's to hold the "null" information
* allocate an array of char's to hold the "null" information
* only if we have a really large targetlist. otherwise we use
* only if we have a really large targetlist. otherwise we use
* the stack.
* the stack.
******************
*/
*/
if
(
nodomains
>
64
)
if
(
nodomains
>
64
)
{
{
...
@@ -1536,23 +1496,21 @@ ExecTargetList(List *targetlist,
...
@@ -1536,23 +1496,21 @@ ExecTargetList(List *targetlist,
fjIsNull
=
&
fjNullArray
[
0
];
fjIsNull
=
&
fjNullArray
[
0
];
}
}
/*
*****************
/*
* evaluate all the expressions in the target list
* evaluate all the expressions in the target list
******************
*/
*/
EV_printf
(
"ExecTargetList: setting target list values
\n
"
);
EV_printf
(
"ExecTargetList: setting target list values
\n
"
);
*
isDone
=
true
;
*
isDone
=
true
;
foreach
(
tl
,
targetlist
)
foreach
(
tl
,
targetlist
)
{
{
/*
*****************
/*
* remember, a target list is a list of lists:
* remember, a target list is a list of lists:
*
*
* ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
* ((<resdom | fjoin> expr) (<resdom | fjoin> expr) ...)
*
*
* tl is a pointer to successive cdr's of the targetlist
* tl is a pointer to successive cdr's of the targetlist
* tle is a pointer to the target list entry in tl
* tle is a pointer to the target list entry in tl
******************
*/
*/
tle
=
lfirst
(
tl
);
tle
=
lfirst
(
tl
);
...
@@ -1626,16 +1584,14 @@ ExecTargetList(List *targetlist,
...
@@ -1626,16 +1584,14 @@ ExecTargetList(List *targetlist,
}
}
}
}
/*
*****************
/*
* form the new result tuple (in the "normal" context)
* form the new result tuple (in the "normal" context)
******************
*/
*/
newTuple
=
(
HeapTuple
)
newTuple
=
(
HeapTuple
)
heap_formtuple
(
targettype
,
values
,
null_head
);
heap_formtuple
(
targettype
,
values
,
null_head
);
/*
*****************
/*
* free the nulls array if we allocated one..
* free the nulls array if we allocated one..
******************
*/
*/
if
(
nodomains
>
64
)
if
(
nodomains
>
64
)
pfree
(
null_head
);
pfree
(
null_head
);
...
@@ -1667,16 +1623,14 @@ ExecProject(ProjectionInfo *projInfo, bool *isDone)
...
@@ -1667,16 +1623,14 @@ ExecProject(ProjectionInfo *projInfo, bool *isDone)
ExprContext
*
econtext
;
ExprContext
*
econtext
;
HeapTuple
newTuple
;
HeapTuple
newTuple
;
/*
*****************
/*
* sanity checks
* sanity checks
******************
*/
*/
if
(
projInfo
==
NULL
)
if
(
projInfo
==
NULL
)
return
(
TupleTableSlot
*
)
NULL
;
return
(
TupleTableSlot
*
)
NULL
;
/*
*****************
/*
* get the projection info we want
* get the projection info we want
******************
*/
*/
slot
=
projInfo
->
pi_slot
;
slot
=
projInfo
->
pi_slot
;
targetlist
=
projInfo
->
pi_targetlist
;
targetlist
=
projInfo
->
pi_targetlist
;
...
@@ -1692,9 +1646,8 @@ ExecProject(ProjectionInfo *projInfo, bool *isDone)
...
@@ -1692,9 +1646,8 @@ ExecProject(ProjectionInfo *projInfo, bool *isDone)
return
(
TupleTableSlot
*
)
NULL
;
return
(
TupleTableSlot
*
)
NULL
;
}
}
/*
*****************
/*
* form a new (result) tuple
* form a new (result) tuple
******************
*/
*/
newTuple
=
ExecTargetList
(
targetlist
,
newTuple
=
ExecTargetList
(
targetlist
,
len
,
len
,
...
@@ -1703,13 +1656,12 @@ ExecProject(ProjectionInfo *projInfo, bool *isDone)
...
@@ -1703,13 +1656,12 @@ ExecProject(ProjectionInfo *projInfo, bool *isDone)
econtext
,
econtext
,
isDone
);
isDone
);
/*
*****************
/*
* store the tuple in the projection slot and return the slot.
* store the tuple in the projection slot and return the slot.
*
*
* If there's no projection target list we don't want to pfree
* If there's no projection target list we don't want to pfree
* the bogus tuple that ExecTargetList passes back to us.
* the bogus tuple that ExecTargetList passes back to us.
* -mer 24 Aug 1992
* -mer 24 Aug 1992
******************
*/
*/
return
(
TupleTableSlot
*
)
return
(
TupleTableSlot
*
)
ExecStoreTuple
(
newTuple
,
/* tuple to store */
ExecStoreTuple
(
newTuple
,
/* tuple to store */
...
...
src/backend/executor/nodeMergejoin.c
View file @
7fe29ece
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
*
*
*
*
* IDENTIFICATION
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.2
1 1999/02/13 23:15:24
momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeMergejoin.c,v 1.2
2 1999/02/22 19:40:10
momjian Exp $
*
*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
*/
*/
...
@@ -26,12 +26,12 @@
...
@@ -26,12 +26,12 @@
* Skip Inner SKIPINNER
* Skip Inner SKIPINNER
* mark inner position JOINMARK
* mark inner position JOINMARK
* do forever { -
* do forever { -
* while (outer
**
inner) { JOINTEST
* while (outer
==
inner) { JOINTEST
* join tuples JOINTUPLES
* join tuples JOINTUPLES
* advance inner position NEXTINNER
* advance inner position NEXTINNER
* } -
* } -
* advance outer position NEXTOUTER
* advance outer position NEXTOUTER
* if (outer
**
mark) { TESTOUTER
* if (outer
==
mark) { TESTOUTER
* restore inner position to mark TESTOUTER
* restore inner position to mark TESTOUTER
* continue -
* continue -
* } else { -
* } else { -
...
@@ -42,7 +42,7 @@
...
@@ -42,7 +42,7 @@
* } -
* } -
*
*
* Skip Outer { SKIPOUTER
* Skip Outer { SKIPOUTER
* if (inner
**
outer) Join Tuples JOINTUPLES
* if (inner
==
outer) Join Tuples JOINTUPLES
* while (outer < inner) SKIPOUTER
* while (outer < inner) SKIPOUTER
* advance outer SKIPOUTER
* advance outer SKIPOUTER
* if (outer > inner) SKIPOUTER
* if (outer > inner) SKIPOUTER
...
@@ -50,7 +50,7 @@
...
@@ -50,7 +50,7 @@
* } -
* } -
*
*
* Skip Inner { SKIPINNER
* Skip Inner { SKIPINNER
* if (inner
**
outer) Join Tuples JOINTUPLES
* if (inner
==
outer) Join Tuples JOINTUPLES
* while (outer > inner) SKIPINNER
* while (outer > inner) SKIPINNER
* advance inner SKIPINNER
* advance inner SKIPINNER
* if (outer < inner) SKIPINNER
* if (outer < inner) SKIPINNER
...
@@ -475,13 +475,13 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -475,13 +475,13 @@ ExecMergeJoin(MergeJoin *node)
switch
(
mergestate
->
mj_JoinState
)
switch
(
mergestate
->
mj_JoinState
)
{
{
/*
/*
---------------------------------------------------
*
********************************
EXEC_MJ_INITIALIZE
* EXEC_MJ_INITIALIZE
* means that this is the first time ExecMergeJoin() has
* means that this is the first time ExecMergeJoin() has
* been called and so we have to initialize the inner,
* been called and so we have to initialize the inner,
* outer and marked tuples as well as various stuff in the
* outer and marked tuples as well as various stuff in the
* expression context.
********************************
* expression context.
*
*
---------------------------------------------------
*/
*/
case
EXEC_MJ_INITIALIZE
:
case
EXEC_MJ_INITIALIZE
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_INITIALIZE
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_INITIALIZE
\n
"
);
...
@@ -513,7 +513,7 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -513,7 +513,7 @@ ExecMergeJoin(MergeJoin *node)
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
econtext
->
ecxt_outertuple
=
outerTupleSlot
;
mergestate
->
mj_MarkedTupleSlot
->
ttc_tupleDescriptor
=
mergestate
->
mj_MarkedTupleSlot
->
ttc_tupleDescriptor
=
innerTupleSlot
->
ttc_tupleDescriptor
;
innerTupleSlot
->
ttc_tupleDescriptor
;
/* ----------------
/* ----------------
* initialize merge join state to skip inner tuples.
* initialize merge join state to skip inner tuples.
...
@@ -522,12 +522,12 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -522,12 +522,12 @@ ExecMergeJoin(MergeJoin *node)
mergestate
->
mj_JoinState
=
EXEC_MJ_SKIPINNER
;
mergestate
->
mj_JoinState
=
EXEC_MJ_SKIPINNER
;
break
;
break
;
/*
/*
---------------------------------------------------
*
******************************** EXEC_MJ_JOINMARK means
*
EXEC_MJ_JOINMARK
* we have just found a new outer tuple and a possible
*
means
we have just found a new outer tuple and a possible
* matching inner tuple. This is the case after the
* matching inner tuple. This is the case after the
* INITIALIZE, SKIPOUTER or SKIPINNER states.
********************************
* INITIALIZE, SKIPOUTER or SKIPINNER states.
*
*
----------------------------------------------------
*/
*/
case
EXEC_MJ_JOINMARK
:
case
EXEC_MJ_JOINMARK
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_JOINMARK
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_JOINMARK
\n
"
);
...
@@ -538,16 +538,16 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -538,16 +538,16 @@ ExecMergeJoin(MergeJoin *node)
mergestate
->
mj_JoinState
=
EXEC_MJ_JOINTEST
;
mergestate
->
mj_JoinState
=
EXEC_MJ_JOINTEST
;
break
;
break
;
/*
/*
----------------------------------------------------
*
******************************** EXEC_MJ_JOINTEST means
*
EXEC_MJ_JOINTEST
* we have two tuples which might satisify the merge
*
means
we have two tuples which might satisify the merge
* clause, so we test them.
* clause, so we test them.
*
*
* If they do satisify, then we join them and move on to the
* If they do satisify, then we join them and move on to the
* next inner tuple (EXEC_MJ_JOINTUPLES).
* next inner tuple (EXEC_MJ_JOINTUPLES).
*
*
* If they do not satisify then advance to next outer tuple.
********************************
* If they do not satisify then advance to next outer tuple.
*
*
------------------------------------------------------
*/
*/
case
EXEC_MJ_JOINTEST
:
case
EXEC_MJ_JOINTEST
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_JOINTEST
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_JOINTEST
\n
"
);
...
@@ -561,12 +561,12 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -561,12 +561,12 @@ ExecMergeJoin(MergeJoin *node)
mergestate
->
mj_JoinState
=
EXEC_MJ_NEXTOUTER
;
mergestate
->
mj_JoinState
=
EXEC_MJ_NEXTOUTER
;
break
;
break
;
/*
/*
----------------------------------------------------
*
********************************
EXEC_MJ_JOINTUPLES
* EXEC_MJ_JOINTUPLES
* means we have two tuples which satisified the merge
* means we have two tuples which satisified the merge
* clause so we join them and then proceed to get the next
* clause so we join them and then proceed to get the next
* inner tuple (EXEC_NEXT_INNER).
********************************
* inner tuple (EXEC_NEXT_INNER).
*
*
----------------------------------------------------
*/
*/
case
EXEC_MJ_JOINTUPLES
:
case
EXEC_MJ_JOINTUPLES
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_JOINTUPLES
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_JOINTUPLES
\n
"
);
...
@@ -596,12 +596,12 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -596,12 +596,12 @@ ExecMergeJoin(MergeJoin *node)
}
}
break
;
break
;
/*
/*
--------------------------------------------------
*
********************************
EXEC_MJ_NEXTINNER
* EXEC_MJ_NEXTINNER
* means advance the inner scan to the next tuple. If the
* means advance the inner scan to the next tuple. If the
* tuple is not nil, we then proceed to test it against
* tuple is not nil, we then proceed to test it against
* the join qualification.
********************************
* the join qualification.
*
*
----------------------------------------------------
*/
*/
case
EXEC_MJ_NEXTINNER
:
case
EXEC_MJ_NEXTINNER
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_NEXTINNER
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_NEXTINNER
\n
"
);
...
@@ -620,18 +620,20 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -620,18 +620,20 @@ ExecMergeJoin(MergeJoin *node)
mergestate
->
mj_JoinState
=
EXEC_MJ_JOINTEST
;
mergestate
->
mj_JoinState
=
EXEC_MJ_JOINTEST
;
break
;
break
;
/*
/*
--------------------------------------------------
*
********************************
EXEC_MJ_NEXTOUTER
* EXEC_MJ_NEXTOUTER
* means
* means
*
* outer inner
* outer inner outer tuple - 5 5 - marked tuple 5 5
* outer tuple - 5 5 - marked tuple
* 6 6 - inner tuple 7 7
* 5 5
* 6 6 - inner tuple
* 7 7
*
*
* we know we just bumped into the first inner tuple >
* we know we just bumped into the first inner tuple >
* current outer tuple so get a new outer tuple and then
* current outer tuple so get a new outer tuple and then
* proceed to test it against the marked tuple
* proceed to test it against the marked tuple
* (EXEC_MJ_TESTOUTER)
********************************
* (EXEC_MJ_TESTOUTER)
*
*
-------------------------------------------------
*/
*/
case
EXEC_MJ_NEXTOUTER
:
case
EXEC_MJ_NEXTOUTER
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_NEXTOUTER
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_NEXTOUTER
\n
"
);
...
@@ -654,35 +656,40 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -654,35 +656,40 @@ ExecMergeJoin(MergeJoin *node)
mergestate
->
mj_JoinState
=
EXEC_MJ_TESTOUTER
;
mergestate
->
mj_JoinState
=
EXEC_MJ_TESTOUTER
;
break
;
break
;
/*
/*
---------------------------------------------------
*
******************************** EXEC_MJ_TESTOUTER If
*
EXEC_MJ_TESTOUTER
* the new outer tuple and the marked tuple satisify the
*
If
the new outer tuple and the marked tuple satisify the
* merge clause then we know we have duplicates in the
* merge clause then we know we have duplicates in the
* outer scan so we have to restore the inner scan to the
* outer scan so we have to restore the inner scan to the
* marked tuple and proceed to join the new outer tuples
* marked tuple and proceed to join the new outer tuples
* with the inner tuples (EXEC_MJ_JOINTEST)
* with the inner tuples (EXEC_MJ_JOINTEST)
*
*
* This is the case when
* This is the case when
* outer inner
* 4 5 - marked tuple
* outer tuple - 5 5
* new outer tuple - 5 5
* 6 8 - inner tuple
* 7 12
*
*
* outer inner 4 5 - marked tuple outer tuple - 5 5
* new outer tuple = marked tuple
* new outer tuple - 5 5 6 8 - inner tuple 7 12
*
*
* new outer tuple = marked tuple
* If the outer tuple fails the test, then we know we have
* to proceed to skip outer tuples until outer >= inner
* (EXEC_MJ_SKIPOUTER).
*
*
* If the outer tuple fails the test, then we know we have to
* This is the case when
* proceed to skip outer tuples until outer >= inner
* (EXEC_MJ_SKIPOUTER).
*
*
* This is the case when
* outer inner
* 5 5 - marked tuple
* outer tuple - 5 5
* new outer tuple - 6 8 - inner tuple
* 7 12
*
*
* outer inner 5 5 - marked tuple outer tuple - 5 5
* new outer tuple - 6 8 - inner tuple 7 12
*
* new outer tuple > marked tuple
*
***************************
*
*
* new outer tuple > marked tuple
*
*
* -----------------------------------------------------------
*/
*/
case
EXEC_MJ_TESTOUTER
:
case
EXEC_MJ_TESTOUTER
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_TESTOUTER
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_TESTOUTER
\n
"
);
...
@@ -746,27 +753,23 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -746,27 +753,23 @@ ExecMergeJoin(MergeJoin *node)
}
}
break
;
break
;
/*
/*
--------------------------------------------------
*
********************************
EXEC_MJ_SKIPOUTER
* EXEC_MJ_SKIPOUTER
* means skip over tuples in the outer plan until we find
* means skip over tuples in the outer plan until we find
* an outer tuple > current inner tuple.
* an outer tuple > current inner tuple.
*
*
* For example:
* For example:
*
*
* outer inner 5 5 5 5 outer tuple - 6 8 -
* outer inner
* inner tuple 7 12 8 14
* 5 5
* 5 5
* outer tuple - 6 8 - inner tuple
* 7 12
* 8 14
*
*
*
w
e have to advance the outer scan until we find the outer
*
W
e have to advance the outer scan until we find the outer
* 8.
* 8.
*
* ------------------------------------------------
**************************
*
*
*
*
*
*
*
*/
*/
case
EXEC_MJ_SKIPOUTER
:
case
EXEC_MJ_SKIPOUTER
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_SKIPOUTER
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_SKIPOUTER
\n
"
);
...
@@ -848,27 +851,22 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -848,27 +851,22 @@ ExecMergeJoin(MergeJoin *node)
mergestate
->
mj_JoinState
=
EXEC_MJ_JOINMARK
;
mergestate
->
mj_JoinState
=
EXEC_MJ_JOINMARK
;
break
;
break
;
/*
/*
------------------------------------------------
*
********************************
EXEC_MJ_SKIPINNER
* EXEC_MJ_SKIPINNER
* means skip over tuples in the inner plan until we find
* means skip over tuples in the inner plan until we find
* an inner tuple > current outer tuple.
* an inner tuple > current outer tuple.
*
*
* For example:
* For example:
* outer inner
* 5 5
* 5 5
* outer tuple - 12 8 - inner tuple
* 14 10
* 17 12
*
*
* outer inner 5 5 5 5 outer tuple - 12 8 - inner
* We have to advance the inner scan until we find the inner
* tuple 14 10 17 12
*
* we have to advance the inner scan until we find the inner
* 12.
* 12.
*
* ---------------------------------------------------
**************************
*
*
*
*
*
*
*
*/
*/
case
EXEC_MJ_SKIPINNER
:
case
EXEC_MJ_SKIPINNER
:
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_SKIPINNER
\n
"
);
MJ_printf
(
"ExecMergeJoin: EXEC_MJ_SKIPINNER
\n
"
);
...
@@ -971,10 +969,8 @@ ExecMergeJoin(MergeJoin *node)
...
@@ -971,10 +969,8 @@ ExecMergeJoin(MergeJoin *node)
break
;
break
;
/*
/*
* ******************************** if we get here it
* If we get here it means our code is messed up and so we
* means our code is fucked up and so we just end the join
* just end the join prematurely.
* prematurely. ********************************
*
*/
*/
default:
default:
elog
(
NOTICE
,
"ExecMergeJoin: invalid join state. aborting"
);
elog
(
NOTICE
,
"ExecMergeJoin: invalid join state. aborting"
);
...
...
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