diff --git a/src/common/backend/parser/parse_node.cpp b/parse_node.cpp similarity index 84% rename from src/common/backend/parser/parse_node.cpp rename to parse_node.cpp index 3430ad52e..bc0ee9b9c 100644 --- a/src/common/backend/parser/parse_node.cpp +++ b/parse_node.cpp @@ -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;