-
Notifications
You must be signed in to change notification settings - Fork 175
Callinto 5stable #937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Callinto 5stable #937
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| -- | ||
| -- Const squashing functionality | ||
| -- | ||
| \set EXECUTE_RUN_PREPARE on | ||
| CREATE EXTENSION pg_stat_statements; | ||
|
|
||
| -- | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -90,6 +90,7 @@ static bool IsParseDynDoStmt = true; | |
| static bool HasPgParam = false; | ||
| static bool DoStmtCheckVar = false; | ||
| static bool IsBindByName = false; | ||
| static bool IsDynCallStmt = false; | ||
|
|
||
| /* | ||
| * store the OraParam name and position | ||
|
|
@@ -575,6 +576,7 @@ push_oraparam_stack(void) | |
| IsParseDynDoStmt = true; | ||
| HasPgParam = false; | ||
| DoStmtCheckVar = false; | ||
| IsDynCallStmt = false; | ||
| new->level = 1; | ||
| } | ||
| else | ||
|
|
@@ -657,8 +659,14 @@ calculate_oraparamnumber(const char* name) | |
| for (i = 0; i < CurrentOraParamNode->param_count; ++i) | ||
| { | ||
| if (strcmp(CurrentOraParamNode->params[i].name, name) == 0) | ||
| { | ||
| return CurrentOraParamNode->params[i].number; | ||
| { | ||
| /* ORA-06578: output parameter cannot be a duplicate bind */ | ||
| if (IsDynCallStmt) | ||
| ereport(ERROR, | ||
| (errcode(ERRCODE_AMBIGUOUS_PARAMETER), | ||
| errmsg("output parameter cannot be a duplicate bind"))); | ||
| else | ||
| return CurrentOraParamNode->params[i].number; | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -689,6 +697,15 @@ calculate_oraparamnumbers(List *parsetree_list) | |
| { | ||
| Node *parsetree = (Node *)lfirst(parsetree_item); | ||
|
|
||
| if (nodeTag(parsetree) == T_RawStmt && | ||
| nodeTag(((RawStmt *)parsetree)->stmt) == T_CallStmt && | ||
| CurrentOraParamNode && | ||
| CurrentOraParamNode->param_count == 0) | ||
| setdynamic_callparser(true); | ||
| else | ||
| /* In any case, it should't affect other statements in the list */ | ||
| setdynamic_callparser(false); | ||
|
|
||
|
Comment on lines
+700
to
+708
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major Avoid global parser state for CallStmt detection; scope per-walk. IsDynCallStmt is toggled globally per top-level node. This can leak across nested parses or subsequent items. Prefer computing a local “isCallCtx” based on the node being walked and pass it via walker state, or push it on the existing OraParam stack. Minimal fix: limit the scope by setting/restoring the previous value within this loop. - if (nodeTag(parsetree) == T_RawStmt &&
+ bool prev = IsDynCallStmt;
+ if (nodeTag(parsetree) == T_RawStmt &&
nodeTag(((RawStmt *)parsetree)->stmt) == T_CallStmt &&
CurrentOraParamNode &&
CurrentOraParamNode->param_count == 0)
setdynamic_callparser(true);
else
/* In any case, it should't affect other statements in the list */
setdynamic_callparser(false);
+ (void)0; /* walk */
if (calculate_oraparamnumbers_walker(parsetree, NULL) == true)
return true;
+ /* restore */
+ setdynamic_callparser(prev);
🤖 Prompt for AI Agents |
||
| if (calculate_oraparamnumbers_walker(parsetree, NULL) == true) | ||
| return true; | ||
| } | ||
|
|
@@ -2491,6 +2508,16 @@ raw_calculate_oraparamnumbers_walker(Node *node, | |
| return true; | ||
| } | ||
| break; | ||
| case T_CallStmt: | ||
| { | ||
| CallStmt *callstmt = (CallStmt *)node; | ||
|
|
||
| if (walker(callstmt->funccall, context)) | ||
| return true; | ||
| if (walker(callstmt->hostvariable, context)) | ||
| return true; | ||
| } | ||
| break; | ||
|
|
||
| default: | ||
| break; | ||
|
|
@@ -2584,6 +2611,15 @@ get_bindByName(void) | |
| return IsBindByName; | ||
| } | ||
|
|
||
| /* | ||
| * set dynamic CallStmt parser status | ||
| */ | ||
| void | ||
| setdynamic_callparser(bool value) | ||
| { | ||
| IsDynCallStmt = value; | ||
| } | ||
|
|
||
| int | ||
| calculate_oraparamname_position(Node *parsetree, char ***paramnames) | ||
| { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Guard scanbuf slicing and sanitize the constructed assignment
Building n->callinto via pnstrdup(scanbuf + @2, @3 - @2) assumes valid locations. If @2 is -1 or @3 <= @2 (comments/whitespace/lexer quirks), this can underflow or slice garbage. Also, the captured text may include trailing spaces.
Example:
Also verify OraParamRef has all fields initialized (indicator, datatype, etc.) or zeroed by makeNode to avoid uninitialized reads downstream.
🏁 Script executed:
Length of output: 308
🏁 Script executed:
Length of output: 3991
🏁 Script executed:
Length of output: 133
🏁 Script executed:
Length of output: 828
🏁 Script executed:
Length of output: 986
🏁 Script executed:
Length of output: 2917
🏁 Script executed:
Length of output: 1619
🏁 Script executed:
Length of output: 1309
🏁 Script executed:
Length of output: 853
🏁 Script executed:
Length of output: 773
Fix scanbuf slicing bounds checking; verify grammar conflicts remain at 0; OraParamRef field initialization is complete but fragile
Bounds on
@2and@3are not validated before slicing. Parser locations can be -1 (indicating unknown position), which would causepnstrdup(base + (-1), len)to underflow. The same unguarded pattern appears at lines 12521 and 12545 forstmt_literal. Add validation:Apply the same fix to lines 12521 and 12545. OraParamRef initialization (lines 1263–1268) is complete for all struct fields but the pattern is fragile; consider initializing all fields explicitly in future. Verify
%expect 0still holds after grammar changes via build output.📝 Committable suggestion
🤖 Prompt for AI Agents