diff --git a/TestTasks/tropaquin/parse_node.md b/TestTasks/tropaquin/parse_node.md new file mode 100644 index 0000000000000000000000000000000000000000..2bc0026c35c6989d05c90aa8bf67819a493822c3 --- /dev/null +++ b/TestTasks/tropaquin/parse_node.md @@ -0,0 +1,23 @@ +作用:为查询树制作解析节点 + +重要函数解读: +1、ParseState* make_parsestate(ParseState* parentParseState); +作用:分配并初始化一个新的ParseState。 +流程:数据传入目前状态->初始化一个新状态ParseState* pstate = NULL;->设置状态的参数值pstate = (ParseState*)palloc0(sizeof(ParseState));->从父节点复制钩子pstate->p_sourcetext = parentParseState->p_sourcetext;->数据返回新状态return pstate; +2、void free_parsestate(ParseState* pstate); +作用:释放一个ParseState和任何附属资源。 +流程:数据传入目前状态->检测状态是否为空Assert(pstate != NULL);->判断resno的个数是否超出限制,超出则抛出错误if (pstate->p_next_resno - 1 > MaxTupleAttributeNumber)->判断目标关系是否为空,空则关闭堆if (pstate->p_target_relation != NULL)->释放资源pfree_ext(pstate); +3、Var* ts_make_var(ParseState* pstate, RangeTblEntry* rte, int attrno, int location); +作用:对时间序列表识别隐藏的列类型,并返回NULL,或者为一个由RTE识别的属性建立一个Var节点,为其他属性建立attrno节点 +流程:数据初始化Var* result = NULL;->获取运行时错误属性类型get_rte_attribute_type(rte, attrno, &vartypeid, &type_mod, &varcollid);->为由运行环境和attrno标识的属性构建一个Var节点result = makeVar(vnum, attrno, vartypeid, type_mod, varcollid, sublevels_up); +4、Oid transformArrayType(Oid* arrayType, int32* arrayTypmod); +作用:识别下标操作中涉及的类型。 +流程:数据传入->数据初始化Oid origArrayType = *arrayType;->提取实际模组类型*arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);->获取数组的类型元组type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*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);->获取数组元素结构elementType = type_struct_array->typelem;->判断是否为数组类型,不是则抛出错误if (elementType == InvalidOid)->释放系统内存ReleaseSysCache(type_tuple_array);->返回数组元素类型return elementType; +tips:在输入时,arrayType/arrayTypmod识别要下标的输入值的类型,如果有必要,这些会被修改,以确定实际的数组类型和typmod,并且返回数组的元素类型。 如果输入值不是一个数组类型,就会产生一个错误 +5、ArrayRef* transformArraySubscripts(ParseState* pstate, Node* arrayBase, Oid arrayType, Oid elementType,int32 arrayTypMod, List* indirection, Node* assignFrom); +作用:转换数组的下标,用于数组获取和数组赋值。 +流程:数据传入->数据初始化->如果调用者不确定元素类型,即元素类型为无效OID,则转换arrayType/arrayTypMod类型elementType = transformArrayType(&arrayType, &arrayTypMod)->预扫描简介列表,看看是否有双下标foreach (idx, indirection)->如果索引文件不为空,则标记为已切片A_Indices* ai = (A_Indices*)lfirst(idx);->如果已经切片且索引文件不为空,转换表达式的值AssertEreport(IsA(ai, A_Indices), MOD_OPT, "");->如果执行数组存储,则强制源值为正确的类型parser_errposition(pstate, exprLocation(assignFrom))));->构建ArrayRef节点aref = makeNode(ArrayRef); +tips:在数组获取中,会得到一个源数组值,于是产生一个表达式,代表提取单个数组元素或数组切片的结果。对于这两种情况,如果源数组是域上的数组类型,则结果是基数组类型或其元素类型。 +6、Const* make_const(ParseState* pstate, Value* value, int location); +作用:当没有明确的常量类型时,使用此函数将一个 Value 节点转换为常量的 “自然 “类型的 Const 节点。 +流程:数据传入->数据初始化->根据节点类型进行转化switch (nodeTag(value))->转换为常量的“natural”类型的Const节点con = makeConst(typid,-1,InvalidOid, typelen,val,false,typebyval); tips:对于整数和浮点数,我们根据数字的值转换为int4、int8或numeric类型。也会转换成int2,但在需要进行额外的处理。 \ No newline at end of file