parse_node #18

Open
qbkrr wants to merge 2 commits from qbkrr/openGauss-server:master into master
1 changed files with 35 additions and 32 deletions

View File

@ -39,11 +39,11 @@ static void pcb_error_callback(void* arg);
*
* Caller should eventually release the ParseState via free_parsestate().
*/
ParseState* make_parsestate(ParseState* parentParseState)
ParseState* make_parsestate(ParseState* parentParseState)//分配并初始化一个新的ParseState。
{
ParseState* pstate = NULL;
ParseState* pstate = NULL;//数据传入目前状态 初始化一个新状态
pstate = (ParseState*)palloc0(sizeof(ParseState));
pstate = (ParseState*)palloc0(sizeof(ParseState));//设置状态的参数值
pstate->parentParseState = parentParseState;
@ -60,7 +60,7 @@ ParseState* make_parsestate(ParseState* parentParseState)
pstate->p_rawdefaultlist = NIL;
if (parentParseState != NULL) {
pstate->p_sourcetext = parentParseState->p_sourcetext;
pstate->p_sourcetext = parentParseState->p_sourcetext;////从父节点复制钩子
/* all hooks are copied from parent */
pstate->p_pre_columnref_hook = parentParseState->p_pre_columnref_hook;
pstate->p_post_columnref_hook = parentParseState->p_post_columnref_hook;
@ -76,30 +76,30 @@ ParseState* make_parsestate(ParseState* parentParseState)
pstate->p_describeco_hook_state = parentParseState->p_describeco_hook_state;
}
return pstate;
return pstate;//数据返回新状态
}
/*
* free_parsestate
* Release a ParseState and any subsidiary resources.
*/
void free_parsestate(ParseState* pstate)
void free_parsestate(ParseState* pstate)//释放一个ParseState和任何附属资源。
{
Assert(pstate != NULL);
Assert(pstate != NULL);//数据传入目前状态->检测状态是否为空
/*
* Check that we did not produce too many resnos; at the very least we
* cannot allow more than 2^16, since that would exceed the range of a
* AttrNumber. It seems safest to use MaxTupleAttributeNumber.
*/
if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber) {
if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber) {//判断resno的个数是否超出限制超出则抛出错误
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("target lists can have at most %d entries", MaxTupleAttributeNumber)));
}
if (pstate->p_target_relation != NULL) {
if (pstate->p_target_relation != NULL) {//判断目标关系是否为空,空则关闭堆
heap_close(pstate->p_target_relation, NoLock);
}
pfree_ext(pstate);
pfree_ext(pstate);//释放资源
}
/*
@ -189,21 +189,21 @@ static void pcb_error_callback(void* arg)
* For timeseries table to identify hidden column type and return NULL or
* build a Var node for an attribute identified by RTE and attrno for others.
*/
Var* ts_make_var(ParseState* pstate, RangeTblEntry* rte, int attrno, int location)
Var* ts_make_var(ParseState* pstate, RangeTblEntry* rte, int attrno, int location)//对时间序列表识别隐藏的列类型并返回NULL或者为一个由RTE识别的属性建立一个Var节点为其他属性建立attrno节点
{
Oid var_type_id;
int32 type_mod;
Oid var_collid;
int kv_type = ATT_KV_UNDEFINED;
get_rte_attribute_type(rte, attrno, &var_type_id, &type_mod, &var_collid, &kv_type);
get_rte_attribute_type(rte, attrno, &var_type_id, &type_mod, &var_collid, &kv_type);//获取运行时错误属性类型
if (kv_type == ATT_KV_HIDE) {
return NULL;
}
Var* result = NULL;
Var* result = NULL;//数据初始化
int vnum, sublevels_up;
vnum = RTERangeTablePosn(pstate, rte, &sublevels_up);
result = makeVar(vnum, attrno, var_type_id, type_mod, var_collid, sublevels_up);
result = makeVar(vnum, attrno, var_type_id, type_mod, var_collid, sublevels_up);//为由运行环境和attrno标识的属性构建一个Var节点
result->location = location;
return result;
}
@ -237,9 +237,10 @@ Var* make_var(ParseState* pstate, RangeTblEntry* rte, int attrno, int location)
* array's element type is returned. An error is thrown if the input isn't
* an array type.
*/
Oid transformArrayType(Oid* arrayType, int32* arrayTypmod)
//tips在输入时arrayType/arrayTypmod识别要下标的输入值的类型如果有必要这些会被修改以确定实际的数组类型和typmod并且返回数组的元素类型。 如果输入值不是一个数组类型,就会产生一个错误
Oid transformArrayType(Oid* arrayType, int32* arrayTypmod)//识别下标操作中涉及的类型。
{
Oid origArrayType = *arrayType;
Oid origArrayType = *arrayType;//数据传入->数据初始化
Oid elementType;
HeapTuple type_tuple_array;
Form_pg_type type_struct_array;
@ -251,26 +252,26 @@ Oid transformArrayType(Oid* arrayType, int32* arrayTypmod)
* itself. (Note that we provide no method whereby the creator of a
* domain over an array type could hide its ability to be subscripted.)
*/
*arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);
*arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);//提取实际模组类型
/* Get the type tuple for the array */
type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType));
type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType));//获取数组的类型元组
if (!HeapTupleIsValid(type_tuple_array)) {
ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for type %u", *arrayType)));
ereport(ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for type %u", *arrayType)));//判断堆积元组是否有效
}
type_struct_array = (Form_pg_type)GETSTRUCT(type_tuple_array);
type_struct_array = (Form_pg_type)GETSTRUCT(type_tuple_array);//获取数组结构
/* needn't check typisdefined since this will fail anyway */
elementType = type_struct_array->typelem;
if (elementType == InvalidOid) {
elementType = type_struct_array->typelem;//获取数组元素结构
if (elementType == InvalidOid) {//判断是否为数组类型,不是则抛出错误
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("cannot subscript type %s because it is not an array", format_type_be(origArrayType))));
}
ReleaseSysCache(type_tuple_array);
ReleaseSysCache(type_tuple_array);//释放系统内存
return elementType;
return elementType;//返回数组元素类型
}
/*
@ -301,7 +302,7 @@ Oid transformArrayType(Oid* arrayType, int32* arrayTypmod)
* indirection Untransformed list of subscripts (must not be NIL)
* assignFrom NULL for array fetch, else transformed expression for source.
*/
ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arrayType, Oid elementType,
ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arrayType, Oid elementType,//转换数组的下标,用于数组获取和数组赋值。
int32 arrayTypMod, List* indirection, Node* assignFrom)
{
bool isSlice = false;
@ -317,7 +318,7 @@ ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arra
* by transformArrayType, ie, smash domain to base type.
*/
if (!OidIsValid(elementType)) {
elementType = transformArrayType(&arrayType, &arrayTypMod);
elementType = transformArrayType(&arrayType, &arrayTypMod);//数据传入->数据初始化->如果调用者不确定元素类型即元素类型为无效OID则转换arrayType/arrayTypMod类型
}
/*
* A list containing only single subscripts refers to a single array
@ -328,7 +329,7 @@ ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arra
* there are any double subscripts.
*/
foreach (idx, indirection) {
A_Indices* ai = (A_Indices*)lfirst(idx);
A_Indices* ai = (A_Indices*)lfirst(idx);//如果索引文件不为空,则标记为已切片
if (ai->lidx != NULL) {
isSlice = true;
@ -339,11 +340,12 @@ ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arra
/*
* Transform the subscript expressions.
*/
//tips在数组获取中会得到一个源数组值于是产生一个表达式代表提取单个数组元素或数组切片的结果。对于这两种情况如果源数组是域上的数组类型则结果是基数组类型或其元素类型。
foreach (idx, indirection) {
A_Indices* ai = (A_Indices*)lfirst(idx);
Node* subexpr = NULL;
AssertEreport(IsA(ai, A_Indices), MOD_OPT, "");
AssertEreport(IsA(ai, A_Indices), MOD_OPT, "");//如果已经切片且索引文件不为空,转换表达式的值
if (isSlice) {
if (ai->lidx) {
subexpr = transformExpr(pstate, ai->lidx);
@ -354,7 +356,7 @@ ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arra
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("array subscript must have type integer"),
parser_errposition(pstate, exprLocation(ai->lidx))));
parser_errposition(pstate, exprLocation(ai->lidx))));//如果执行数组存储,则强制源值为正确的类型
}
} else {
/* Make a constant 1 */
@ -445,7 +447,8 @@ ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arra
* but additional cleanup is needed before we can do that; there are
* too many examples that fail if we try.
*/
Const* make_const(ParseState* pstate, Value* value, int location)
// tips对于整数和浮点数我们根据数字的值转换为int4、int8或numeric类型。也会转换成int2但在需要进行额外的处理。
Const* make_const(ParseState* pstate, Value* value, int location)//当没有明确的常量类型时,使用此函数将一个 Value 节点转换为常量的 “自然 “类型的 Const 节点。
{
Const* con = NULL;
Datum val;
@ -455,7 +458,7 @@ Const* make_const(ParseState* pstate, Value* value, int location)
bool typebyval = false;
ParseCallbackState pcbstate;
switch (nodeTag(value)) {
switch (nodeTag(value)) {//数据传入->数据初始化->根据节点类型进行转化
case T_Integer:
val = Int32GetDatum(intVal(value));
@ -525,7 +528,7 @@ Const* make_const(ParseState* pstate, Value* value, int location)
case T_Null:
/* return a null const */
con = makeConst(UNKNOWNOID, -1, InvalidOid, -2, (Datum)0, true, false);
con = makeConst(UNKNOWNOID, -1, InvalidOid, -2, (Datum)0, true, false);//转换为常量的“natural”类型的Const节点
con->location = location;
return con;