Skip to content

Commit

Permalink
Fix crash in sp_describe_undeclared_parameters (#2687)
Browse files Browse the repository at this point in the history
In our previous attempt of fixing sp_describe_undeclared_parameters related crash, we missed some corner cases where few variables will be left NULL if is_sp_describe_undeclared_parameters is marked as false. Then when we try to access those variables, we get seg fault.
In this commit, we fix it by adding extra check on is_sp_describe_undeclared_parameters.
Issues Resolved

BABEL-5068
Signed-off-by: Shameem Ahmed [email protected]
Signed-off-by: Shameem Ahmed <[email protected]>
(cherry picked from commit 2c54161)
  • Loading branch information
ahmed-shameem committed Jun 26, 2024
1 parent 5ecafd6 commit 3d61b0b
Showing 1 changed file with 110 additions and 86 deletions.
196 changes: 110 additions & 86 deletions contrib/babelfishpg_tsql/src/procedures.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,10 @@ handle_bool_expr_rec(BoolExpr *expr, List *list, bool is_sp_describe_undeclared_
ListCell *lc;
A_Expr *xpr;
ColumnRef *ref;

if (is_sp_describe_undeclared_parameters && !is_supported_case_sp_describe_undeclared_parameters)
return list;

foreach(lc, args)
{
Expr *arg = (Expr *) lfirst(lc);
Expand Down Expand Up @@ -577,6 +581,9 @@ handle_where_clause_attnums(ParseState *pstate, Node *w_clause, List *target_att
char *name;
int attrno;

if (is_sp_describe_undeclared_parameters && !is_supported_case_sp_describe_undeclared_parameters)
return target_attnums;

if (w_clause && nodeTag(w_clause) == T_A_Expr)
{
A_Expr *where_clause = (A_Expr *)w_clause;
Expand Down Expand Up @@ -669,6 +676,9 @@ handle_where_clause_restargets_left(ParseState *pstate, Node *w_clause, List *ex
char *name;
int attrno;

if (is_sp_describe_undeclared_parameters && !is_supported_case_sp_describe_undeclared_parameters)
return extra_restargets;

if (w_clause && nodeTag(w_clause) == T_A_Expr)
{
A_Expr *where_clause = (A_Expr *)w_clause;
Expand Down Expand Up @@ -776,6 +786,9 @@ handle_where_clause_restargets_right(ParseState *pstate, Node *w_clause, List *e
Value *field;
ResTarget *res;

if (is_sp_describe_undeclared_parameters && !is_supported_case_sp_describe_undeclared_parameters)
return extra_restargets;

if (w_clause && nodeTag(w_clause) == T_A_Expr)
{
A_Expr *where_clause = (A_Expr *)w_clause;
Expand Down Expand Up @@ -962,98 +975,101 @@ sp_describe_undeclared_parameters_internal(PG_FUNCTION_ARGS)
}
}

/*
* Analyze the parsed statement to suggest types for undeclared
* parameters
*/
switch (node_type)
if (is_supported_case_sp_describe_undeclared_parameters)
{
case T_InsertStmt:
rewrite_object_refs(parsetree->stmt);
sql_dialect = sql_dialect_value_old;
insert_stmt = (InsertStmt *) parsetree->stmt;
relation = insert_stmt->relation;
relid = RangeVarGetRelid(relation, NoLock, false);
r = relation_open(relid, AccessShareLock);
pstate = (ParseState *) palloc0(sizeof(ParseState));
pstate->p_target_relation = r;
cols = checkInsertTargets(pstate, insert_stmt->cols, &target_attnums);
break;
case T_UpdateStmt:
rewrite_object_refs(parsetree->stmt);
sql_dialect = sql_dialect_value_old;
update_stmt = (UpdateStmt *) parsetree->stmt;
relation = update_stmt->relation;
relid = RangeVarGetRelid(relation, NoLock, false);
r = relation_open(relid, AccessShareLock);
pstate = (ParseState *) palloc0(sizeof(ParseState));
pstate->p_target_relation = r;
cols = list_copy(update_stmt->targetList);

/*
* Add attnums to cols based on targetList
*/
foreach(lc, cols)
{
ResTarget *col = (ResTarget *) lfirst(lc);
char *name = col->name;
int attrno;
/*
* Analyze the parsed statement to suggest types for undeclared
* parameters
*/
switch (node_type)
{
case T_InsertStmt:
rewrite_object_refs(parsetree->stmt);
sql_dialect = sql_dialect_value_old;
insert_stmt = (InsertStmt *) parsetree->stmt;
relation = insert_stmt->relation;
relid = RangeVarGetRelid(relation, NoLock, false);
r = relation_open(relid, AccessShareLock);
pstate = (ParseState *) palloc0(sizeof(ParseState));
pstate->p_target_relation = r;
cols = checkInsertTargets(pstate, insert_stmt->cols, &target_attnums);
break;
case T_UpdateStmt:
rewrite_object_refs(parsetree->stmt);
sql_dialect = sql_dialect_value_old;
update_stmt = (UpdateStmt *) parsetree->stmt;
relation = update_stmt->relation;
relid = RangeVarGetRelid(relation, NoLock, false);
r = relation_open(relid, AccessShareLock);
pstate = (ParseState *) palloc0(sizeof(ParseState));
pstate->p_target_relation = r;
cols = list_copy(update_stmt->targetList);

attrno = attnameAttNum(pstate->p_target_relation, name, false);
if (attrno == InvalidAttrNumber)
/*
* Add attnums to cols based on targetList
*/
foreach(lc, cols)
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
name,
RelationGetRelationName(pstate->p_target_relation))));
ResTarget *col = (ResTarget *) lfirst(lc);
char *name = col->name;
int attrno;

attrno = attnameAttNum(pstate->p_target_relation, name, false);
if (attrno == InvalidAttrNumber)
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
name,
RelationGetRelationName(pstate->p_target_relation))));
}
target_attnums = lappend_int(target_attnums, attrno);
}
target_attnums = lappend_int(target_attnums, attrno);
}
target_attnums = handle_where_clause_attnums(pstate, update_stmt->whereClause, target_attnums, true);
extra_restargets = handle_where_clause_restargets_left(pstate, update_stmt->whereClause, extra_restargets, true);
target_attnums = handle_where_clause_attnums(pstate, update_stmt->whereClause, target_attnums, true);
extra_restargets = handle_where_clause_restargets_left(pstate, update_stmt->whereClause, extra_restargets, true);

cols = list_concat_copy(cols, extra_restargets);
break;
case T_DeleteStmt:
rewrite_object_refs(parsetree->stmt);
sql_dialect = sql_dialect_value_old;
delete_stmt = (DeleteStmt *) parsetree->stmt;
relation = delete_stmt->relation;
relid = RangeVarGetRelid(relation, NoLock, false);
r = relation_open(relid, AccessShareLock);
pstate = (ParseState *) palloc0(sizeof(ParseState));
pstate->p_target_relation = r;
cols = NIL;

/*
* Add attnums to cols based on targetList
*/
foreach(lc, cols)
{
ResTarget *col = (ResTarget *) lfirst(lc);
char *name = col->name;
int attrno;
cols = list_concat_copy(cols, extra_restargets);
break;
case T_DeleteStmt:
rewrite_object_refs(parsetree->stmt);
sql_dialect = sql_dialect_value_old;
delete_stmt = (DeleteStmt *) parsetree->stmt;
relation = delete_stmt->relation;
relid = RangeVarGetRelid(relation, NoLock, false);
r = relation_open(relid, AccessShareLock);
pstate = (ParseState *) palloc0(sizeof(ParseState));
pstate->p_target_relation = r;
cols = NIL;

attrno = attnameAttNum(pstate->p_target_relation, name, false);
if (attrno == InvalidAttrNumber)
/*
* Add attnums to cols based on targetList
*/
foreach(lc, cols)
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
name,
RelationGetRelationName(pstate->p_target_relation))));
ResTarget *col = (ResTarget *) lfirst(lc);
char *name = col->name;
int attrno;

attrno = attnameAttNum(pstate->p_target_relation, name, false);
if (attrno == InvalidAttrNumber)
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("column \"%s\" of relation \"%s\" does not exist",
name,
RelationGetRelationName(pstate->p_target_relation))));
}
target_attnums = lappend_int(target_attnums, attrno);
}
target_attnums = lappend_int(target_attnums, attrno);
}
target_attnums = handle_where_clause_attnums(pstate, delete_stmt->whereClause, target_attnums, true);
extra_restargets = handle_where_clause_restargets_left(pstate, delete_stmt->whereClause, extra_restargets, true);
target_attnums = handle_where_clause_attnums(pstate, delete_stmt->whereClause, target_attnums, true);
extra_restargets = handle_where_clause_restargets_left(pstate, delete_stmt->whereClause, extra_restargets, true);

cols = list_concat_copy(cols, extra_restargets);
break;
default:
is_supported_case_sp_describe_undeclared_parameters = false;
break;
cols = list_concat_copy(cols, extra_restargets);
break;
default:
is_supported_case_sp_describe_undeclared_parameters = false;
break;
}
}

if (is_supported_case_sp_describe_undeclared_parameters)
Expand Down Expand Up @@ -1121,7 +1137,7 @@ sp_describe_undeclared_parameters_internal(PG_FUNCTION_ARGS)
break;
}

if (!(list_length(values_list) > 1) && is_supported_case_sp_describe_undeclared_parameters)
if (is_supported_case_sp_describe_undeclared_parameters && !(list_length(values_list) > 1))
{
foreach(lc, values_list)
{
Expand All @@ -1130,6 +1146,9 @@ sp_describe_undeclared_parameters_internal(PG_FUNCTION_ARGS)
int numvalues = 0;
int numtotalvalues = list_length(sublist);

if (!is_supported_case_sp_describe_undeclared_parameters)
break;

undeclaredparams->paramnames = (char **) palloc(sizeof(char *) * numtotalvalues);
undeclaredparams->paramindexes = (int *) palloc(sizeof(int) * numtotalvalues);
if (list_length(sublist) != num_target_attnums)
Expand Down Expand Up @@ -1170,8 +1189,13 @@ sp_describe_undeclared_parameters_internal(PG_FUNCTION_ARGS)
default:
break;
}
fields = columnref->fields;
if (!(nodeTag(columnref) != T_ColumnRef && nodeTag(parsetree->stmt) != T_DeleteStmt))

if (is_supported_case_sp_describe_undeclared_parameters)
fields = columnref->fields;

if (is_supported_case_sp_describe_undeclared_parameters &&
!(nodeTag(columnref) != T_ColumnRef &&
nodeTag(parsetree->stmt) != T_DeleteStmt))
{
foreach(fieldcell, fields)
{
Expand Down

0 comments on commit 3d61b0b

Please sign in to comment.