In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)05/31 Report--
< parameterCount; i++) { if (paramNames[i] == PointerGetDatum(NULL)) paramNames[i] = CStringGetTextDatum(""); } *parameterNames = construct_array(paramNames, parameterCount, TEXTOID, -1, false, 'i'); } else *parameterNames = NULL;}三、跟踪分析 测试脚本 create or replace function func_test(pi_v1 in int,pi_v2 varchar,pio_v3 inout varchar,po_v4 out int,po_v5 out varchar)returns record as$$declarebegin raise notice 'pi_v1 := %,pi_v2 := %,pi_v3 := %',pi_v1,pi_v2,pio_v3; pio_v3 := 'pio_v3 i/o'; po_v4 := 100; po_v5 := 'po_v5 out';end;$$ LANGUAGE plpgsql; 启动GDB跟踪 (gdb) cContinuing.Breakpoint 1, interpret_function_parameter_list (pstate=0x10edc88, parameters=0x10c7d30, languageOid=13581, objtype=OBJECT_FUNCTION, parameterTypes=0x7ffec5c6ea88, allParameterTypes=0x7ffec5c6ea80, parameterModes=0x7ffec5c6ea78, parameterNames=0x7ffec5c6ea70, parameterDefaults=0x7ffec5c6ea68, variadicArgType=0x7ffec5c6ea64, requiredResultType=0x7ffec5c6ea60) at functioncmds.c:195195 int parameterCount = list_length(parameters);(gdb) 输入参数,语言为pl/pgsql,对象类型是function,存在有5个参数 (gdb) p *pstate$1 = {parentParseState = 0x0, p_sourcetext = 0x10c6ed8 "create or replace function func_test(pi_v1 in int,pi_v2 varchar,pio_v3 inout varchar,po_v4 out int,po_v5 out varchar)\nreturns record \nas\n$$\ndeclare\nbegin\n raise notice 'pi_v1 := %,pi_v2 := %,pi_v3 :="..., p_rtable = 0x0, p_joinexprs = 0x0, p_joinlist = 0x0, p_namespace = 0x0, p_lateral_active = false, p_ctenamespace = 0x0, p_future_ctes = 0x0, p_parent_cte = 0x0, p_target_relation = 0x0, p_target_rangetblentry = 0x0, p_is_insert = false, p_windowdefs = 0x0, p_expr_kind = EXPR_KIND_NONE, p_next_resno = 1, p_multiassign_exprs = 0x0, p_locking_clause = 0x0, p_locked_from_parent = false, p_resolve_unknowns = true, p_queryEnv = 0x0, p_hasAggs = false, p_hasWindowFuncs = false, p_hasTargetSRFs = false, p_hasSubLinks = false, p_hasModifyingCTE = false, p_last_srf = 0x0, p_pre_columnref_hook = 0x0, p_post_columnref_hook = 0x0, p_paramref_hook = 0x0, p_coerce_param_hook = 0x0, p_ref_hook_state = 0x0}(gdb) (gdb) p *parameters$2 = {type = T_List, length = 5, head = 0x10c7d08, tail = 0x10c8480}(gdb) 初始化相关变量 (gdb) n197 int inCount = 0;(gdb) 201 int outCount = 0;(gdb) 202 int varCount = 0;(gdb) 203 bool have_names = false;(gdb) 204 bool have_defaults = false;(gdb) 208 *variadicArgType = InvalidOid; /* default result */(gdb) 209 *requiredResultType = InvalidOid; /* default result */(gdb) 211 inTypes = (Oid *) palloc(parameterCount * sizeof(Oid));(gdb) 212 allTypes = (Datum *) palloc(parameterCount * sizeof(Datum));(gdb) 213 paramModes = (Datum *) palloc(parameterCount * sizeof(Datum));(gdb) 214 paramNames = (Datum *) palloc0(parameterCount * sizeof(Datum));(gdb) 215 *parameterDefaults = NIL;(gdb) 218 i = 0;(gdb) 219 foreach(x, parameters)(gdb) 开始循环,第一个参数,名称为pi_v1,参数类型为pg_catalog.int4 (gdb) 221 FunctionParameter *fp = (FunctionParameter *) lfirst(x);(gdb) 222 TypeName *t = fp->ArgType; (gdb) 223 bool isinput = false (gdb) p * fp$4 = {type = T_FunctionParameter, name = 0x10c7b60 "pi_v1", argType = 0x10c7c58, mode = FUNC_PARAM_IN, defexpr = 0x0} (gdb) p * fp- > argType$5 = {type = T_TypeName, names = 0x10c7bd0, typeOid = 0, setof = false, pct_type = false, typmods = 0x0, typemod =-1, arrayBounds = 0x0, location = 46} (gdb) p * fp- > argType- > names$6 = {type = type, T_List = 2, T_List = T_List Tail = 0x10c7ba8} (gdb) p * (Node *) fp- > argType- > names- > head- > data.ptr_value$7 = {type = T_String} (Value *) fp- > argType- > names- > head- > data.ptr_value$8 = {type = T_String, val = {ival = 12340746, str = 0xbc4e0a "pg_catalog"}} (gdb) p * (Value *) fp- > argType- > names- > head- > next- > data.ptr_value$9 = {type = T_String, val = {ival = 12320664 Str = 0xbbff98 "int4"}} (gdb) p * tasking 10 = {type = T_TypeName, names = 0x10c7bd0, typeOid = 0, setof = false, pct_type = false, typmods = 0x0, typemod =-1, arrayBounds = 0x0, location = 46} (gdb)
Get the tuple of the corresponding type in pg_type
(gdb) n228 typtup = LookupTypeName (NULL, t, NULL, false) (gdb) 229 if (typtup) (gdb) p * typtup$11 = {t_len = 176,t_self = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 8}, t_tableOid = 1247, t_data = 0x7ff12a2c3c40} (gdb) p * typtup- > t_data$12 = {t_choice = {t_heap = {t_xmin = 1, t_xmax = 0, t_field3 = {t_cid = 0, t_xvac = 0}} T_datum = {datum_len_ = 1, datum_typmod = 0, datum_typeid = 0}}, t_ctid = {ip_blkid = {bi_hi = 0, bi_lo = 0}, ip_posid = 8}, t_infomask2 = 31, t_infomask = 2305, t_hoff = 32' T_bits = 0x7ff12a2c3c57 "\ 377\ 377\ 377\ 017"} (gdb) xswab 16c typtup- > tweak data-> t_bits0x7ff12a2c3c57:-1'\ 377'-1'\ 377'-1'\ 377' 15'\ 017' 0000 '0000' 0000 '0000' 0'\ 000'0x7ff12a2c3c5f: 0'\ 00023'\ 027' 0000 '0000' 0000 '105i' 110' N '116t' (gdb) xswap 64c typtup- > tweak data-> t_bits0x7ff12a2c3c57:-1'\ 377'-1'\ 377'-1'\ 377' 15'\ 017' 0'\ 000 '0000' 0000 '0000' 0000'23'\ 0270' 0000 '0000' 0000 '105' i110 'n116' t'0x7ff12a2c3c67: 52' 4 '0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,000,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,000,0,0,000,0,0,000,0,0,000,0,0,000,0,000,0,0,000,0,0,000,0,0,000,0, 0 '000'0x7ff12a2c3c7f: 0', 000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0. '\ 000'0x7ff12a2c3c8f: 0'\ 000 GETSTRUCT 0'\ 000 oid 0'\ 000 million 0'\ 000 million 0'(Form_pg_type) GETSTRUCT (typtup)) $14 = {oid = 23 Typname = {data = "int4",'\ 000'}, typnamespace = 11, typowner = 10, typlen = 4, typbyval = true, typtype = 98 'baked, typcategory = 78' Nucleus, typispreferred = false, typisdefined = true, typdelim = 44',', typrelid = 0, typelem = 0, typarray = 1007, typinput = 42, typoutput = 43, typreceive = 2406, typsend = 2407, typmodin = 0, typmodout = 0, typanalyze = 0, typalign = 105ified, typstorage = 112112paired, typnotnull = false, typbasetype = 0 Typtypmod =-1, typndims = 0, typcollation = 0} (gdb)
Get the oid of type
(gdb) n251 toid = typeTypeId (typtup); (gdb) 252 ReleaseSysCache (typtup); (gdb) 263 aclresult = pg_type_aclcheck (toid, GetUserId (), ACL_USAGE); (gdb) p toid$15 = 23 (gdb)
Check permissions
263 aclresult = pg_type_aclcheck (toid, GetUserId (), ACL_USAGE); (gdb) p toid$15 = 23 (gdb) n264 if (aclresult! = ACLCHECK_OK) (gdb) 267 if (t-> setof) (gdb)
Processing input parameters
(gdb) p t-> setof$16 = false (gdb) n283 if (objtype = = OBJECT_PROCEDURE) (gdb) 293 if (fp- > mode! = FUNC_PARAM_OUT & & fp- > mode! = FUNC_PARAM_TABLE) (gdb) 296 if (varCount > 0) (gdb) 300 inTypes [inCount++] = toid; (gdb) 301 isinput = true (gdb) 305 if (fp- > mode! = FUNC_PARAM_IN & & fp- > mode! = FUNC_PARAM_VARIADIC) (gdb) 314 if (fp- > mode = = FUNC_PARAM_VARIADIC) (gdb) (gdb) n334 allTypes [I] = ObjectIdGetDatum (toid); (gdb) 336 paramModes [I] = CharGetDatum (fp- > mode) (gdb) 338 if (fp- > name & & fp- > name [0]) (gdb) p fp- > mode$17 = FUNC_PARAM_IN (gdb) n348 foreach (px, parameters) (gdb)
Determine whether the name is the same.
(gdb) n350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px); (gdb) 352 if (prevfp = = fp) (gdb) 353 break; (gdb)
If there is no duplicate name, set the relevant variable and write the address of fp- > name to the paramNames pointer array.
373 paramNames [I] = CStringGetTextDatum (fp- > name); (gdb) 374have_names = true; (gdb) 377if (fp- > defexpr) (gdb) p paramNames [0] $18 = 17751776
Next parameter
(gdb) n420 if (isinput & & have_defaults) (gdb) 426 iTunes; (gdb) p * fp- > defexprCannot access memory at address 0x0 (gdb) n219 foreach (x, parameters) (gdb) 221 FunctionParameter * fp = (FunctionParameter *) lfirst (x); (gdb) 222TypeName * t = fp- > argType; (gdb) 223 bool isinput = false; (gdb) 228 typtup = LookupTypeName (NULL, t, NULL, false) (gdb) (gdb) n229 if (typtup) (gdb) 231 if (! ((Form_pg_type) GETSTRUCT (typtup))-> typisdefined) (gdb) 251 toid = typeTypeId (typtup); (gdb) 252 ReleaseSysCache (typtup) (gdb) p * ((Form_pg_type) GETSTRUCT (typtup)) $22 = {oid = 1043, typname = {data = "varchar",'\ 000'}, typnamespace = 11, typowner = 10, typlen =-1, typbyval = false, typtype = 98 'baked, typcategory = 83' Smits, typispreferred = false, typisdefined = true, typdelim = 44',', typrelid = 0, typelem = 0, typarray = 1015, typinput = 1046, typoutput = 1047, typreceive = 2432, typsend = 2433, typmodin = 2915, typmodout = 2916, typanalyze = 0 Typalign = 105', typstorage = 120'x, typnotnull = false, typbasetype = 0, typtypmod =-1, typndims = 0, typcollation = 100} (gdb) n263 aclresult = pg_type_aclcheck (toid, GetUserId (), ACL_USAGE) (gdb) 264 if (aclresult! = ACLCHECK_OK) (gdb) 267if (t-> setof) (gdb) 283if (objtype = = OBJECT_PROCEDURE) (gdb) 293if (fp- > mode! = FUNC_PARAM_OUT & & fp- > mode! = FUNC_PARAM_TABLE) (gdb) 296if (varCount > 0) (gdb) 300inTypes [inCount++] = toid; (gdb) 301isinput = true (gdb) 305 if (fp- > mode! = FUNC_PARAM_IN & & fp- > mode! = FUNC_PARAM_VARIADIC) (gdb) 314 if (fp- > mode = = FUNC_PARAM_VARIADIC) (gdb) 334 allTypes [I] = ObjectIdGetDatum (toid); (gdb) 336 paramModes [I] = CharGetDatum (fp- > mode); (gdb)
Determine whether the parameters are duplicated
338 if (fp- > name & & fp- > name [0]) (gdb) 348 foreach (px, parameters) (gdb) p fp- > name$23 = 0x10c7d68 "pi_v2" (gdb) p fp- > name [0] $24 = 112p' (gdb) n350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) p * prevfp$25 = {type = T_FunctionParameter, name = 0x10c7b60 "pi_v1", argType = 0x10c7c58, mode = FUNC_PARAM_IN Defexpr = 0x0} (gdb) n355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 357 (prevfp- > mode = = FUNC_PARAM_OUT | | (gdb) 356 fp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 358 prevfp- > mode = = FUNC_PARAM_TABLE) (gdb) 357 (prevfp- > mode = FUNC_PARAM_OUT | | (gdb) 360 if ((prevfp-) > mode = = FUNC_PARAM_IN | | (gdb) 362 (fp- > mode = = FUNC_PARAM_OUT | | (gdb) 361 prevfp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 363 fp- > mode = = FUNC_PARAM_TABLE)) (gdb) 362 (fp- > mode = = FUNC_PARAM_OUT | | (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & (gdb) 366 strcmp (prevfp- > name) Fp- > name) = = 0) (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) p * prevfp$26 = {type = T_FunctionParameter, name = 0x10c7d68 "pi_v2", argType = 0x10c7e60, mode = FUNC_PARAM_IN, defexpr = 0x0} (gdb) p * fp$27 = {type = T_FunctionParameter, name = 0x10c7d68 "pi_v2", argType = 0x10c7e60, mode = FUNC_PARAM_IN, defexpr = 0x0} (gdb) n353 break; (gdb) 373 paramNames [I] = CStringGetTextDatum (fp- > fp-) (gdb) 374 have_names = true; (gdb) 377 if (fp- > defexpr) (gdb) 420 if (isinput & & have_defaults) (gdb) 426 iTunes; (gdb) 219 foreach (x, parameters)
The next parameter, which is an INOUT parameter (recorded in both the IN and OUT arrays)
(gdb) n221 FunctionParameter * fp = (FunctionParameter *) lfirst (x); (gdb) 222TypeName * t = fp- > argType; (gdb) 223 bool isinput = false; (gdb) 228 typtup = LookupTypeName (NULL, t, NULL, false); (gdb) 229 if (typtup) (gdb) 231 if (! (Form_pg_type) GETSTRUCT (typtup))-> typisdefined) (gdb) 251 toid = typeTypeId (typtup) (gdb) p * ((Form_pg_type) GETSTRUCT (typtup)) $28 = {oid = 1043, typname = {data = "varchar",'\ 000'}, typnamespace = 11, typowner = 10, typlen =-1, typbyval = false, typtype = 98 'baked, typcategory = 83' Smits, typispreferred = false, typisdefined = true, typdelim = 44',', typrelid = 0, typelem = 0, typarray = 1015, typinput = 1046, typoutput = 1047, typreceive = 2432, typsend = 2433, typmodin = 2915, typmodout = 2916, typanalyze = 0 Typalign = 105'I, typstorage = 120'x, typnotnull = false, typbasetype = 0, typtypmod =-1, typndims = 0, typcollation = 100} (gdb) n252 ReleaseSysCache (typtup) (gdb) 263 aclresult = pg_type_aclcheck (toid, GetUserId (), ACL_USAGE); (gdb) 264 if (aclresult! = ACLCHECK_OK) (gdb) 267 if (t-> setof) (gdb) 283 if (objtype = = OBJECT_PROCEDURE) (gdb) 293 if (fp- > mode! = FUNC_PARAM_OUT & fp- > mode! = FUNC_PARAM_TABLE) (gdb) 296 if (varCount > 0) (gdb) 300 inTypes [inCount++] = toid (gdb) 301 isinput = true; (gdb) 305 if (fp- > mode! = FUNC_PARAM_IN & & fp- > mode! = FUNC_PARAM_VARIADIC) (gdb) 307 if (objtype = = OBJECT_PROCEDURE) (gdb) 309 else if (outCount = = 0) / * save first output param's type * / (gdb) 310 * requiredResultType = toid; (gdb) 311 outCount++ (gdb) 314 if (fp- > mode = = FUNC_PARAM_VARIADIC) (gdb) 334 allTypes [I] = ObjectIdGetDatum (toid); (gdb) 336 paramModes [I] = CharGetDatum (fp- > mode); (gdb) 338 if (fp- > name & & fp- > name [0]) (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) p * prevfp$29 = {type = T_FunctionParameter, name = 0x10c7b60 "pi_v1", argType = 0x10c7c58, mode = FUNC_PARAM_IN, defexpr = 0x0} (gdb) n355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 356 fp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) p * fp$30 = {type = T_FunctionParameter, name = 0x10c7f38 "pio_v3", argType = 0x10c8030 Mode = FUNC_PARAM_INOUT Defexpr = 0x0} (gdb) n355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 360 if ((prevfp- > mode = = FUNC_PARAM_IN | | (gdb) 362 (fp- > mode = = FUNC_PARAM_OUT | | (gdb) 361prevfp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 363fp- > mode = = FUNC_PARAM_TABLE)) (gdb) 362 (fp-) > mode = = FUNC_PARAM_OUT | | (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 366 strcmp (prevfp- > name) Fp- > name) = = 0) (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 356 fp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 360 if (prevfp- > mode = = FUNC_PARAM_IN | | (gdb) 362 (fp- > mode = FUNC_PARAM_OUT | |) Gdb) 361 prevfp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 363 fp- > mode = = FUNC_PARAM_TABLE)) (gdb) 362 (fp- > mode = = FUNC_PARAM_OUT | | (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 366 strcmp (prevfp- > name) Fp- > name) = = 0) (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) 353 break; (gdb) 373 paramNames [I] = CStringGetTextDatum (fp- > name); (gdb) 374 have_names = true; (gdb) 377 if (fp- > defexpr) (gdb) 420 if (isinput & have_defaults) (gdb) 426 iTunes; (gdb) 219 foreach (x, parameters)
The next parameter, the OUT parameter
(gdb) n221 FunctionParameter * fp = (FunctionParameter *) lfirst (x); (gdb) n222 TypeName * t = fp- > argType; (gdb) 223 bool isinput = false; (gdb) 228 typtup = LookupTypeName (NULL, t, NULL, false); (gdb) 229 if (typtup) (gdb) 231 if (! (Form_pg_type) GETSTRUCT (typtup))-> typisdefined) (gdb) 251 toid = typeTypeId (typtup) (gdb) p * ((Form_pg_type) GETSTRUCT (typtup)) $31 = {oid = 23, typname = {data = "int4",'\ 000'}, typnamespace = 11, typowner = 10, typlen = 4, typbyval = true, typtype = 98 'baked, typcategory = 78' Night, typispreferred = false, typisdefined = true, typdelim = 44',', typrelid = 0, typelem = 0, typarray = 1007, typinput = 42, typoutput = 43, typreceive = 2406, typsend = 2407, typmodin = 0, typmodout = 0, typanalyze = 0 Typalign = 105', typstorage = 112', typnotnull = false, typbasetype = 0, typtypmod =-1, typndims = 0, typcollation = 0} (gdb) n252 ReleaseSysCache (typtup) (gdb) 263 aclresult = pg_type_aclcheck (toid, GetUserId (), ACL_USAGE) (gdb) 264 if (aclresult! = ACLCHECK_OK) (gdb) 267if (t-> setof) (gdb) 283if (objtype = = OBJECT_PROCEDURE) (gdb) 293if (fp- > mode! = FUNC_PARAM_OUT & & fp- > mode! = FUNC_PARAM_TABLE) (gdb) 305if (fp- > mode! = FUNC_PARAM_IN & & fp- > mode! = FUNC_PARAM_VARIADIC) (gdb) 307if (objtype = OBJECT_PROCEDURE) (gdb ) 309 else if (outCount = = 0) / * save first output param's type * / (gdb) 311 outCount++ (gdb) 314 if (fp- > mode = = FUNC_PARAM_VARIADIC) (gdb) 334 allTypes [I] = ObjectIdGetDatum (toid); (gdb) 336 paramModes [I] = CharGetDatum (fp- > mode); (gdb) 338 if (fp- > name & & fp- > name [0]) (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) p * prevfp$32 = {type = T_FunctionParameter, name = 0x10c7b60 "pi_v1", argType = 0x10c7c58, mode = FUNC_PARAM_IN, defexpr = 0x0} (gdb) p * fp$33 = {type = T_FunctionParameter, name = 0x10c8108 "po_v4", argType = 0x10c8200, mode = FUNC_PARAM_OUT Defexpr = 0x0} (gdb) n356 fp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 360 if ((prevfp- > mode = = FUNC_PARAM_IN | | (gdb) 362 (fp- > mode = = FUNC_PARAM_OUT | | (gdb) 361prevfp- > mode = = FUNC_PARAM_VARIADIC) & (gdb) 364 continue (gdb) n348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 356 fp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 360 if (prevfp- > mode = = FUNC_PARAM_IN | | (gdb) 362 (fp- > mode = FUNC_PARAM_OUT | |) Gdb) 361 prevfp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 364 continue (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 356 fp- > mode = = FUNC_PARAM_VARIADIC) & & (gdb) 355 if ((fp- > mode = = FUNC_PARAM_IN | | (gdb) 360 if (prevfp- > mode = = FUNC_PARAM_IN | | (gdb) 361prevfp- > mode = FUNC_PARAM_VARIADIC) & & (gdb) 360 if ((prevfp- > mode = = FUNC_PARAM_IN | | (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 366 strcmp (prevfp- > name) Fp- > name) = = 0) (gdb) 365 if (prevfp- > name & & prevfp- > name [0] & & (gdb) 348 foreach (px, parameters) (gdb) 350 FunctionParameter * prevfp = (FunctionParameter *) lfirst (px) (gdb) 352 if (prevfp = = fp) (gdb) 353 break; (gdb) 373 paramNames [I] = CStringGetTextDatum (fp- > name); (gdb) 374 have_names = true; (gdb) 377 if (fp- > defexpr) (gdb) 420 if (isinput & have_defaults) (gdb) 426 iTunes; (gdb) 219 foreach (x, parameters)
Next parameter
.
Complete the parsing of all parameters
(gdb) 432 if (outCount > 0 | | varCount > 0) (gdb) 434 * allParameterTypes = construct_array (allTypes, parameterCount, OIDOID, (gdb) n436 * parameterModes = construct_array (paramModes, parameterCount, CHAROID, (gdb) 438 if (outCount > 1) (gdb) 439 * requiredResultType = RECORDOID) (gdb) p * allTypes$34 = 23 (gdb) p allTypes [4] $35 = 1043 (gdb) n438 if (outCount > 1) (gdb) 448 if (have_names) (gdb) 450 for (I = 0; I
< parameterCount; i++)(gdb) 452 if (paramNames[i] == PointerGetDatum(NULL))(gdb) 450 for (i = 0; i < parameterCount; i++)(gdb) 452 if (paramNames[i] == PointerGetDatum(NULL))(gdb) 450 for (i = 0; i < parameterCount; i++)(gdb) 452 if (paramNames[i] == PointerGetDatum(NULL))(gdb) 450 for (i = 0; i < parameterCount; i++)(gdb) 452 if (paramNames[i] == PointerGetDatum(NULL))(gdb) 450 for (i = 0; i < parameterCount; i++)(gdb) 452 if (paramNames[i] == PointerGetDatum(NULL))(gdb) 450 for (i = 0; i < parameterCount; i++)(gdb) 455 *parameterNames = construct_array(paramNames, parameterCount, TEXTOID,(gdb) 460 }(gdb) CreateFunction (pstate=0x10edc88, stmt=0x10c88c8) at functioncmds.c:10651065 if (stmt->Is_procedure) (gdb) at this point, the study on "analyzing interpret_function_parameter_list functions in PostgreSQL CreateFunction" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.