105#define EXEC_MJ_INITIALIZE_OUTER 1
106#define EXEC_MJ_INITIALIZE_INNER 2
107#define EXEC_MJ_JOINTUPLES 3
108#define EXEC_MJ_NEXTOUTER 4
109#define EXEC_MJ_TESTOUTER 5
110#define EXEC_MJ_NEXTINNER 6
111#define EXEC_MJ_SKIP_TEST 7
112#define EXEC_MJ_SKIPOUTER_ADVANCE 8
113#define EXEC_MJ_SKIPINNER_ADVANCE 9
114#define EXEC_MJ_ENDOUTER 10
115#define EXEC_MJ_ENDINNER 11
151#define MarkInnerTuple(innerTupleSlot, mergestate) \
152 ExecCopySlot((mergestate)->mj_MarkedTupleSlot, (innerTupleSlot))
177 Oid *mergecollations,
178 bool *mergereversals,
179 bool *mergenullsfirst,
190 foreach(cl, mergeclauses)
194 Oid opfamily = mergefamilies[iClause];
195 Oid collation = mergecollations[iClause];
196 bool reversed = mergereversals[iClause];
197 bool nulls_first = mergenullsfirst[iClause];
204 elog(
ERROR,
"mergejoin clause is not an OpExpr");
224 elog(
ERROR,
"cannot merge using non-equality operator %u",
254 elog(
ERROR,
"missing support function %d(%u,%u) in opfamily %u",
389 bool nulleqnull =
false;
463 MJ_printf(
"ExecMergeJoin: returning outer fill tuple\n");
494 MJ_printf(
"ExecMergeJoin: returning inner fill tuple\n");
525 *is_const_false =
true;
538#ifdef EXEC_MERGEJOINDEBUG
545 printf(
"==== outer tuple ====\n");
557 printf(
"==== inner tuple ====\n");
569 printf(
"==== marked tuple ====\n");
579 printf(
"******** ExecMergeTupleDump ********\n");
581 ExecMergeTupleDumpOuter(mergestate);
582 ExecMergeTupleDumpInner(mergestate);
583 ExecMergeTupleDumpMarked(mergestate);
648 MJ_printf(
"ExecMergeJoin: EXEC_MJ_INITIALIZE_OUTER\n");
678 MJ_printf(
"ExecMergeJoin: nothing in outer subplan\n");
696 MJ_printf(
"ExecMergeJoin: EXEC_MJ_INITIALIZE_INNER\n");
733 MJ_printf(
"ExecMergeJoin: nothing in inner subplan\n");
758 MJ_printf(
"ExecMergeJoin: EXEC_MJ_JOINTUPLES\n");
786 qualResult = (joinqual == NULL ||
819 qualResult = (otherqual == NULL ||
829 MJ_printf(
"ExecMergeJoin: returning tuple\n");
849 MJ_printf(
"ExecMergeJoin: EXEC_MJ_NEXTINNER\n");
897 if (compareResult == 0)
899 else if (compareResult < 0)
902 elog(
ERROR,
"mergejoin input data is out of order");
950 MJ_printf(
"ExecMergeJoin: EXEC_MJ_NEXTOUTER\n");
988 MJ_printf(
"ExecMergeJoin: end of outer subplan\n");
990 if (doFillInner && !
TupIsNull(innerTupleSlot))
1040 MJ_printf(
"ExecMergeJoin: EXEC_MJ_TESTOUTER\n");
1053 if (compareResult == 0)
1092 else if (compareResult > 0)
1145 elog(
ERROR,
"mergejoin input data is out of order");
1178 MJ_printf(
"ExecMergeJoin: EXEC_MJ_SKIP_TEST\n");
1188 if (compareResult == 0)
1197 else if (compareResult < 0)
1212 MJ_printf(
"ExecMergeJoin: EXEC_MJ_SKIPOUTER_ADVANCE\n");
1250 MJ_printf(
"ExecMergeJoin: end of outer subplan\n");
1252 if (doFillInner && !
TupIsNull(innerTupleSlot))
1274 MJ_printf(
"ExecMergeJoin: EXEC_MJ_SKIPINNER_ADVANCE\n");
1320 MJ_printf(
"ExecMergeJoin: end of inner subplan\n");
1322 if (doFillOuter && !
TupIsNull(outerTupleSlot))
1342 MJ_printf(
"ExecMergeJoin: EXEC_MJ_ENDOUTER\n");
1375 MJ_printf(
"ExecMergeJoin: end of inner subplan\n");
1388 MJ_printf(
"ExecMergeJoin: EXEC_MJ_ENDINNER\n");
1417 MJ_printf(
"ExecMergeJoin: end of outer subplan\n");
1428 elog(
ERROR,
"unrecognized mergejoin state: %d",
1450 "initializing node");
1573 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1574 errmsg(
"RIGHT JOIN is only supported with merge-joinable join conditions")));
1591 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1592 errmsg(
"FULL JOIN is only supported with merge-joinable join conditions")));
1595 elog(
ERROR,
"unrecognized join type: %d",
1604 node->mergeFamilies,
1605 node->mergeCollations,
1606 node->mergeReversals,
1607 node->mergeNullsFirst,
1623 "node initialized");
1639 "ending node processing");
1648 "node processing ended");
#define Assert(condition)
#define OidIsValid(objectId)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ExecMarkPos(PlanState *node)
void ExecReScan(PlanState *node)
void ExecRestrPos(PlanState *node)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ExprState * ExecInitQual(List *qual, PlanState *parent)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
const TupleTableSlotOps TTSOpsVirtual
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecInitResultTupleSlotTL(PlanState *planstate, const TupleTableSlotOps *tts_ops)
TupleTableSlot * ExecInitNullTupleSlot(EState *estate, TupleDesc tupType, const TupleTableSlotOps *tts_ops)
TupleDesc ExecGetResultType(PlanState *planstate)
ExprContext * CreateExprContext(EState *estate)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
void ExecAssignProjectionInfo(PlanState *planstate, TupleDesc inputDesc)
const TupleTableSlotOps * ExecGetResultSlotOps(PlanState *planstate, bool *isfixed)
#define MJ_DEBUG_COMPARE(res)
#define MJ_DEBUG_QUAL(clause, res)
#define MJ_DEBUG_PROC_NODE(slot)
#define MJ_debugtup(slot)
#define InstrCountFiltered1(node, delta)
#define outerPlanState(node)
#define InstrCountFiltered2(node, delta)
#define innerPlanState(node)
struct MergeJoinClauseData * MergeJoinClause
#define EXEC_FLAG_BACKWARD
static TupleTableSlot * ExecProject(ProjectionInfo *projInfo)
#define ResetExprContext(econtext)
static bool ExecQual(ExprState *state, ExprContext *econtext)
static TupleTableSlot * ExecProcNode(PlanState *node)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
#define OidFunctionCall1(functionId, arg1)
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
#define CHECK_FOR_INTERRUPTS()
#define BTSORTSUPPORT_PROC
static MergeJoinClause MJExamineQuals(List *mergeclauses, Oid *mergefamilies, Oid *mergecollations, bool *mergereversals, bool *mergenullsfirst, PlanState *parent)
static int MJCompare(MergeJoinState *mergestate)
struct MergeJoinClauseData MergeJoinClauseData
#define EXEC_MJ_SKIP_TEST
#define EXEC_MJ_JOINTUPLES
static TupleTableSlot * ExecMergeJoin(PlanState *pstate)
#define EXEC_MJ_SKIPOUTER_ADVANCE
#define MarkInnerTuple(innerTupleSlot, mergestate)
#define EXEC_MJ_TESTOUTER
static TupleTableSlot * MJFillOuter(MergeJoinState *node)
void ExecReScanMergeJoin(MergeJoinState *node)
static MJEvalResult MJEvalOuterValues(MergeJoinState *mergestate)
#define EXEC_MJ_INITIALIZE_OUTER
#define EXEC_MJ_SKIPINNER_ADVANCE
MergeJoinState * ExecInitMergeJoin(MergeJoin *node, EState *estate, int eflags)
#define EXEC_MJ_NEXTOUTER
void ExecEndMergeJoin(MergeJoinState *node)
#define EXEC_MJ_INITIALIZE_INNER
static MJEvalResult MJEvalInnerValues(MergeJoinState *mergestate, TupleTableSlot *innerslot)
#define EXEC_MJ_NEXTINNER
static TupleTableSlot * MJFillInner(MergeJoinState *node)
static bool check_constant_qual(List *qual, bool *is_const_false)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static int list_length(const List *l)
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup)
static int ApplySortComparator(Datum datum1, bool isNull1, Datum datum2, bool isNull2, SortSupport ssup)
#define BTEqualStrategyNumber
MemoryContext ecxt_per_tuple_memory
TupleTableSlot * ecxt_innertuple
TupleTableSlot * ecxt_outertuple
TupleTableSlot * mj_MarkedTupleSlot
TupleTableSlot * mj_NullInnerTupleSlot
ExprContext * mj_InnerEContext
TupleTableSlot * mj_NullOuterTupleSlot
MergeJoinClause mj_Clauses
TupleTableSlot * mj_InnerTupleSlot
ExprContext * mj_OuterEContext
TupleTableSlot * mj_OuterTupleSlot
ExprContext * ps_ExprContext
ProjectionInfo * ps_ProjInfo
ExecProcNodeMtd ExecProcNode
int(* comparator)(Datum x, Datum y, SortSupport ssup)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)