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