parse_node #18
|
|
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue