/* ---------------------------------------------------------------- *ExecSubPlan * *ThisisthemainentrypointforexecutionofaregularSubPlan. *----------------------------------------------------------------
*/
Datum
ExecSubPlan(SubPlanState *node,
ExprContext *econtext, bool *isNull)
{
SubPlan *subplan = node->subplan;
EState *estate = node->planstate->state;
ScanDirection dir = estate->es_direction;
Datum retval;
CHECK_FOR_INTERRUPTS();
/* Set non-null as default */
*isNull = false;
/* Sanity checks */ if (subplan->subLinkType == CTE_SUBLINK)
elog(ERROR, "CTE subplans should not be executed via ExecSubPlan"); if (subplan->setParam != NIL && subplan->subLinkType != MULTIEXPR_SUBLINK)
elog(ERROR, "cannot set parent params from subquery");
/* Force forward-scan mode for evaluation */
estate->es_direction = ForwardScanDirection;
/* Shouldn't have any direct correlation Vars */ if (subplan->parParam != NIL || subplan->args != NIL)
elog(ERROR, "hashed subplan with direct correlation not supported");
for (slot = ExecProcNode(planstate);
!TupIsNull(slot);
slot = ExecProcNode(planstate))
{
TupleDesc tdesc = slot->tts_tupleDescriptor;
Datum rowresult; bool rownull; int col;
ListCell *plst;
if (subLinkType == EXISTS_SUBLINK)
{
found = true;
result = BoolGetDatum(true); break;
}
if (subLinkType == EXPR_SUBLINK)
{ /* cannot allow multiple input tuples for EXPR sublink */ if (found)
ereport(ERROR,
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("more than one row returned by a subquery used as an expression")));
found = true;
result = heap_getattr(node->curTuple, 1, tdesc, isNull); /* keep scanning subplan to make sure there's only one tuple */ continue;
}
if (subLinkType == MULTIEXPR_SUBLINK)
{ /* cannot allow multiple input tuples for MULTIEXPR sublink */ if (found)
ereport(ERROR,
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("more than one row returned by a subquery used as an expression")));
found = true;
/* keep scanning subplan to make sure there's only one tuple */ continue;
}
if (subLinkType == ARRAY_SUBLINK)
{
Datum dvalue; bool disnull;
found = true; /* stash away current value */
Assert(subplan->firstColType == TupleDescAttr(tdesc, 0)->atttypid);
dvalue = slot_getattr(slot, 1, &disnull);
astate = accumArrayResultAny(astate, dvalue, disnull,
subplan->firstColType, oldcontext); /* keep scanning subplan to collect all values */ continue;
}
/* cannot allow multiple input tuples for ROWCOMPARE sublink either */ if (subLinkType == ROWCOMPARE_SUBLINK && found)
ereport(ERROR,
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("more than one row returned by a subquery used as an expression")));
found = true;
/* *ForALL,ANY,andROWCOMPAREsublinks,loaduptheParams *representingthecolumnsofthesub-select,andthenevaluatethe *combiningexpression.
*/
col = 1;
foreach(plst, subplan->paramIds)
{ int paramid = lfirst_int(plst);
ParamExecData *prmdata;
if (subLinkType == ANY_SUBLINK)
{ /* combine across rows per OR semantics */ if (rownull)
*isNull = true; elseif (DatumGetBool(rowresult))
{
result = BoolGetDatum(true);
*isNull = false; break; /* needn't look at any more rows */
}
} elseif (subLinkType == ALL_SUBLINK)
{ /* combine across rows per AND semantics */ if (rownull)
*isNull = true; elseif (!DatumGetBool(rowresult))
{
result = BoolGetDatum(false);
*isNull = false; break; /* needn't look at any more rows */
}
} else
{ /* must be ROWCOMPARE_SUBLINK */
result = rowresult;
*isNull = rownull;
}
}
MemoryContextSwitchTo(oldcontext);
if (subLinkType == ARRAY_SUBLINK)
{ /* We return the result in the caller's context */
result = makeArrayResultAny(astate, oldcontext, true);
} elseif (!found)
{ /* *dealwithemptysubplanresult.result/isNullwerepreviously *initializedcorrectlyforallsublinktypesexceptEXPRand *ROWCOMPARE;forthose,returnNULL.
*/ if (subLinkType == EXPR_SUBLINK ||
subLinkType == ROWCOMPARE_SUBLINK)
{
result = (Datum) 0;
*isNull = true;
} elseif (subLinkType == MULTIEXPR_SUBLINK)
{ /* We don't care about function result, but set the setParams */
foreach(l, subplan->setParam)
{ int paramid = lfirst_int(l);
ParamExecData *prmdata;
if (!subplan->unknownEqFalse)
{ if (ncols == 1)
nbuckets = 1; /* there can only be one entry */ else
{
nbuckets /= 16; if (nbuckets < 1)
nbuckets = 1;
}
/* Reset and switch into the temp context. */
MemoryContextReset(evalContext);
oldContext = MemoryContextSwitchTo(evalContext);
/* *Wecannotreportamatchwithoutcheckingallthefields,butwecan *reportanon-matchassoonaswefindunequalfields.So,start *comparingatthelastfield(leastsignificantsortkey).That'sthe *mostlikelytobedifferentifwearedealingwithsortedinput.
*/
result = false;
for (i = numCols; --i >= 0;)
{
AttrNumber att = matchColIdx[i];
Datum attr1,
attr2; bool isNull1,
isNull2;
attr1 = slot_getattr(slot1, att, &isNull1);
if (isNull1) continue; /* can't prove anything here */
attr2 = slot_getattr(slot2, att, &isNull2);
if (isNull2) continue; /* can't prove anything here */
/* Apply the type-specific equality function */ if (!DatumGetBool(FunctionCall2Coll(&eqfunctions[i],
collations[i],
attr1, attr2)))
{
result = true; /* they are unequal */ break;
}
}
/* Link the SubPlanState to already-initialized subplan */
sstate->planstate = (PlanState *) list_nth(estate->es_subplanstates,
subplan->plan_id - 1);
/* *Thischeckcanfailiftheplannermistakenlyputsaparallel-unsafe *subplanintoaparallelizedsubquery;seeExecSerializePlan.
*/ if (sstate->planstate == NULL)
elog(ERROR, "subplan \"%s\" was not initialized",
subplan->plan_name);
/* Link to parent's state, too */
sstate->parent = parent;
/* *Ifwearegoingtohashthesubqueryoutput,initializerelevantstuff. *(Wedon'tcreatethehashtableuntilneeded,though.)
*/ if (subplan->useHashTable)
{ int ncols,
i;
TupleDesc tupDescLeft;
TupleDesc tupDescRight;
Oid *cross_eq_funcoids;
TupleTableSlot *slot;
FmgrInfo *lhs_hash_funcs;
List *oplist,
*lefttlist,
*righttlist;
ListCell *l;
/* We need a memory context to hold the hash table(s) */
sstate->hashtablecxt =
AllocSetContextCreate(CurrentMemoryContext, "Subplan HashTable Context",
ALLOCSET_DEFAULT_SIZES); /* and a small one for the hash tables to use as temp storage */
sstate->hashtempcxt =
AllocSetContextCreate(CurrentMemoryContext, "Subplan HashTable Temp Context",
ALLOCSET_SMALL_SIZES); /* and a short-lived exprcontext for function evaluation */
sstate->innerecontext = CreateExprContext(estate);
/* Look up the equality function for the RHS type */ if (!get_compatible_hash_operators(opexpr->opno,
NULL, &rhs_eq_oper))
elog(ERROR, "could not find compatible hash operator for operator %u",
opexpr->opno);
sstate->tab_eq_funcoids[i - 1] = get_opcode(rhs_eq_oper);
/* Lookup the associated hash functions */ if (!get_op_hash_functions(opexpr->opno,
&left_hashfn, &right_hashfn))
elog(ERROR, "could not find hash function for hash operator %u",
opexpr->opno);
fmgr_info(left_hashfn, &lhs_hash_funcs[i - 1]);
fmgr_info(right_hashfn, &sstate->tab_hash_funcs[i - 1]);
/* Set collation */
sstate->tab_collations[i - 1] = opexpr->inputcollid;
/* keyColIdx is just column numbers 1..n */
sstate->keyColIdx[i - 1] = i;
if (subLinkType == ANY_SUBLINK ||
subLinkType == ALL_SUBLINK)
elog(ERROR, "ANY/ALL subselect unsupported as initplan"); if (subLinkType == CTE_SUBLINK)
elog(ERROR, "CTE subplans should not be executed via ExecSetParamPlan"); if (subplan->parParam || subplan->args)
elog(ERROR, "correlated subplans should not be executed via ExecSetParamPlan");
/* *Runtheplan.(Ifitneedstoberescanned,thefirstExecProcNode *callwilltakecareofthat.)
*/ for (slot = ExecProcNode(planstate);
!TupIsNull(slot);
slot = ExecProcNode(planstate))
{
TupleDesc tdesc = slot->tts_tupleDescriptor; int i = 1;
if (subLinkType == EXISTS_SUBLINK)
{ /* There can be only one setParam... */ int paramid = linitial_int(subplan->setParam);
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
if (subLinkType == ARRAY_SUBLINK)
{
Datum dvalue; bool disnull;
found = true; /* stash away current value */
Assert(subplan->firstColType == TupleDescAttr(tdesc, 0)->atttypid);
dvalue = slot_getattr(slot, 1, &disnull);
astate = accumArrayResultAny(astate, dvalue, disnull,
subplan->firstColType, oldcontext); /* keep scanning subplan to collect all values */ continue;
}
if (found &&
(subLinkType == EXPR_SUBLINK ||
subLinkType == MULTIEXPR_SUBLINK ||
subLinkType == ROWCOMPARE_SUBLINK))
ereport(ERROR,
(errcode(ERRCODE_CARDINALITY_VIOLATION),
errmsg("more than one row returned by a subquery used as an expression")));
if (subLinkType == ARRAY_SUBLINK)
{ /* There can be only one setParam... */ int paramid = linitial_int(subplan->setParam);
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
/* *Webuildtheresultarrayinquerycontextsoitwon'tdisappear; *toavoidleakingmemoryacrossrepeatedcalls,wehavetoremember *thelatestvalue,muchasforcurTupleabove.
*/ if (node->curArray != PointerGetDatum(NULL))
pfree(DatumGetPointer(node->curArray));
node->curArray = makeArrayResultAny(astate,
econtext->ecxt_per_query_memory, true);
prm->execPlan = NULL;
prm->value = node->curArray;
prm->isnull = false;
} elseif (!found)
{ if (subLinkType == EXISTS_SUBLINK)
{ /* There can be only one setParam... */ int paramid = linitial_int(subplan->setParam);
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
prm->execPlan = NULL;
prm->value = BoolGetDatum(false);
prm->isnull = false;
} else
{ /* For other sublink types, set all the output params to NULL */
foreach(l, subplan->setParam)
{ int paramid = lfirst_int(l);
ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
if (prm->execPlan != NULL)
{ /* Parameter not evaluated yet, so go do it */
ExecSetParamPlan(prm->execPlan, econtext); /* ExecSetParamPlan should have processed this param... */
Assert(prm->execPlan == NULL);
}
}
}
/* sanity checks */ if (subplan->parParam != NIL)
elog(ERROR, "direct correlated subquery unsupported as initplan"); if (subplan->setParam == NIL)
elog(ERROR, "setParam list of initplan is empty"); if (bms_is_empty(planstate->plan->extParam))
elog(ERROR, "extParam set of initplan is empty");
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.39Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.