openGauss源码解析(135)
openGauss源码解析:执行器解析(28)
ExecEvalParamExec函数的作用是获取并返回PARAM_EXEC类型的参数。PARAM_EXEC参数是指内部执行器参数,是需要执行子计划来获取的结果,最后需要将结果返回到上层计划中。核心代码如下:
prm = &(econtext->ecxt_param_exec_vals[thisParamId]); /* 获取econtext中参数 */
if (prm->execPlan != NULL) { /* 判断是否需要生成参数 */
/* 参数还未计算执行此函数*/
ExecSetParamPlan((SubPlanState*)prm->execPlan, econtext);
/*参数计算完计划重置为空*/
Assert(prm->execPlan == NULL);
prm->isConst = true;
prm->valueType = expression->paramtype;
}
*isNull = prm->isnull;
prm->isChanged = true;
return prm->value; /* 返回生成的参数 */
ExecEvalParamExec函数的主要执行流程如下。
(1) 获取econtext中的ecxt_param_exec_vals参数。
(2) 判断子计划是否为空,若不为空则调用ExecSetParamPlan函数执行子计划获取结果,并把计划置为空,当再次执行此函数时,不需要重新执行计划,直接返回已经获取过结果。
(3) 将结果prm->value返回。
ExecEvalParamExec函数的执行流程如图7-21所示。
图7-21 ExecEvalParamExec函数执行流程
ExecEvalParamExtern函数的作用是获取并返回PARAM_EXTERN类型的参数。该参数是指外部传入参数,例如在PBE执行时,PREPARE的语句中的参数,在需要execute语句执行时传入。核心代码如下:
if (paramInfo && thisParamId > 0 && thisParamId <= paramInfo->numParams) {/* 判断参数 */
ParamExternData* prm = ¶mInfo->params[thisParamId - 1];
if (!OidIsValid(prm->ptype) && paramInfo->paramFetch != NULL) /* 获取动态参数 */
(*paramInfo->paramFetch)(paramInfo, thisParamId);
if (OidIsValid(prm->ptype)) { /*检查参数并返回 */
if (prm->ptype != expression->paramtype)
ereport(……);
*isNull = prm->isnull;
if (econtext->is_cursor && prm->ptype == REFCURSOROID) {
CopyCursorInfoData(&econtext->cursor_data, &prm->cursor_data);
econtext->dno = thisParamId - 1;
}
return prm->value;
}
}
ereport(ERROR, (errcode(ERRCODE_UNDEFINED_OBJECT), errmsg("no value found for parameter %d", thisParamId)));
return (Datum)0;
ExecEvalParamExtern函数主要执行流程如下。
(1) 判断PARAM_EXTERN类型的参数否存在,若存在则从ecxt_param_list_info中获取该参数,否则直接报错。
(2) 判断参数是否是动态的,若是动态的则再次获取参数。
(3) 判断参数类型是否符合要求,若符合要求直接返回该参数。
ExecEvalParamExtern函数的执行流程如图7-22所示。
图7-22 ExecEvalParamExtern函数执行流程