Skip to content

Commit

Permalink
[CBRD-24645] When order-by of subquery is copied to main query during…
Browse files Browse the repository at this point in the history
… view merging, rownum of main query is displayed incorrectly (CUBRID#4080)

http://jira.cubrid.org/browse/CBRD-24645

When 'ORDER BY' is copied to the main query during view-merging, I fix so that 'ROWNUM' of the select list of the main query is replaced with 'ORDERBY_NUM'.
  • Loading branch information
shparkcubrid authored Feb 3, 2023
1 parent 6ba7945 commit 3d20edf
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ extern "C"
extern bool pt_has_order_sensitive_agg (PARSER_CONTEXT * parser, PT_NODE * node);
extern bool pt_has_inst_or_orderby_num (PARSER_CONTEXT * parser, PT_NODE * node);
extern bool pt_has_inst_num (PARSER_CONTEXT * parser, PT_NODE * node);
extern bool pt_has_expr_of_inst_in_sel_list (PARSER_CONTEXT * parser, PT_NODE * select_list);
extern bool pt_has_inst_in_where_and_select_list (PARSER_CONTEXT * parser, PT_NODE * node);
extern bool pt_has_inst_or_orderby_num_in_where (PARSER_CONTEXT * parser, PT_NODE * node);
extern void pt_set_correlation_level (PARSER_CONTEXT * parser, PT_NODE * subquery, int level);
Expand Down
38 changes: 38 additions & 0 deletions src/parser/parser_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -3353,6 +3353,44 @@ pt_has_inst_num (PARSER_CONTEXT * parser, PT_NODE * node)
return has_inst_num;
}

/*
* pt_has_expr_of_inst_in_sel_list () - check if tree has an EXPR node having INST_NUM in select list
* return: true if tree has EXPR node having INST_NUM
* parser(in):
* node(in):
*/
bool
pt_has_expr_of_inst_in_sel_list (PARSER_CONTEXT * parser, PT_NODE * select_list)
{
PT_NODE *save_next, *col;

/*
* FIXME!! : remove this check after expanding syntax related to orderby_num().
* This check is needed because the syntax below is not supported.
* 'select orderby_num() + 10 ...'
* Check MSGCAT_SEMANTIC_ORDERBYNUM_SELECT_LIST_ERR error code
* In XASL Generator, 'ordbynum_val' must be created as a regular variable, not db_value.
*/
col = select_list;
while (col)
{
/* cut off next */
save_next = col->next;
col->next = NULL;

if (!PT_IS_INSTNUM (col) && pt_has_inst_num (parser, col))
{
/* find expr of instnum */
col->next = save_next;
return true;
}
col->next = save_next;
col = col->next;
}

return false;
}

/*
* pt_has_inst_in_where_and_select_list ()
* - check if tree has an INST_NUM or ORDERBY_NUM or GROUPBY_NUM node in where and select_list
Expand Down
69 changes: 34 additions & 35 deletions src/parser/view_transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,7 @@ static PUSHABLE_TYPE
mq_is_pushable_subquery (PARSER_CONTEXT * parser, PT_NODE * subquery, PT_NODE * mainquery, PT_NODE * class_spec,
bool is_vclass, PT_NODE * order_by, PT_NODE * class_)
{
PT_NODE *pred, *statement_spec = NULL, *orderby_for;
PT_NODE *pred, *statement_spec = NULL, *orderby_for, *select_list;
CHECK_PUSHABLE_INFO cpi;
bool is_pushable_query, is_outer_joined;
bool is_only_spec, is_rownum_only, is_orderby_for;
Expand All @@ -1690,27 +1690,32 @@ mq_is_pushable_subquery (PARSER_CONTEXT * parser, PT_NODE * subquery, PT_NODE *
case PT_SELECT:
statement_spec = mainquery->info.query.q.select.from;
pred = mainquery->info.query.q.select.where;
select_list = mainquery->info.query.q.select.list;
break;

case PT_UPDATE:
statement_spec = mainquery->info.update.spec;
pred = mainquery->info.update.search_cond;
select_list = NULL;
break;

case PT_DELETE:
statement_spec = mainquery->info.delete_.spec;
pred = mainquery->info.delete_.search_cond;
select_list = NULL;
break;

case PT_INSERT:
/* since INSERT can not have a spec list or statement conditions, there is nothing to check */
statement_spec = mainquery->info.insert.spec;
pred = NULL;
select_list = NULL;
break;

case PT_MERGE:
statement_spec = mainquery->info.merge.into;
pred = mainquery->info.merge.insert.search_cond;
select_list = NULL;
break;

default:
Expand Down Expand Up @@ -1786,7 +1791,7 @@ mq_is_pushable_subquery (PARSER_CONTEXT * parser, PT_NODE * subquery, PT_NODE *
/* subquery has order_by and main query has inst_num or analytic or order-sensitive aggrigation */
if (subquery->info.query.order_by
&& ((!is_rownum_only && pt_has_inst_num (parser, pred)) || pt_has_analytic (parser, mainquery)
|| pt_has_order_sensitive_agg (parser, mainquery)))
|| pt_has_order_sensitive_agg (parser, mainquery) || pt_has_expr_of_inst_in_sel_list (parser, select_list)))
{
/* not pushable */
return NON_PUSHABLE;
Expand Down Expand Up @@ -2019,6 +2024,7 @@ mq_update_order_by (PARSER_CONTEXT * parser, PT_NODE * statement, PT_NODE * quer
PT_NODE *attributes, *attr, *prev_order;
PT_NODE *save_data_type, *node, *result, *order_by;
PT_NODE *free_node = NULL, *save_next, *where;
PT_NODE *ord_num = NULL, *ins_num = NULL, *prev_orderby_for;
int attr_count;
int i;
UINTPTR spec_id;
Expand Down Expand Up @@ -2162,30 +2168,33 @@ mq_update_order_by (PARSER_CONTEXT * parser, PT_NODE * statement, PT_NODE * quer

statement->info.query.order_by = parser_append_node (order_by, statement->info.query.order_by);

where = statement->info.query.q.select.where;
if (where != NULL && PT_EXPR_INFO_IS_FLAGED (where, PT_EXPR_INFO_ROWNUM_ONLY) && statement->info.query.order_by)
/* generate orderby_num(), inst_num() */
if (!(ord_num = parser_new_node (parser, PT_EXPR)) || !(ins_num = parser_new_node (parser, PT_EXPR)))
{
/* replace orderby_num() to inst_num() */
PT_NODE *ord_num = NULL, *ins_num = NULL, *prev_orderby_for;

/* generate orderby_num(), inst_num() */
if (!(ord_num = parser_new_node (parser, PT_EXPR)) || !(ins_num = parser_new_node (parser, PT_EXPR)))
if (ord_num)
{
PT_ERRORm (parser, statement, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_OUT_OF_MEMORY);
return NULL;
parser_free_tree (parser, ord_num);
}
PT_ERRORm (parser, statement, MSGCAT_SET_PARSER_SEMANTIC, MSGCAT_SEMANTIC_OUT_OF_MEMORY);
return NULL;
}
ord_num->type_enum = PT_TYPE_BIGINT;
ord_num->info.expr.op = PT_ORDERBY_NUM;
PT_EXPR_INFO_SET_FLAG (ord_num, PT_EXPR_INFO_ORDERBYNUM_C);

ord_num->type_enum = PT_TYPE_BIGINT;
ord_num->info.expr.op = PT_ORDERBY_NUM;
PT_EXPR_INFO_SET_FLAG (ord_num, PT_EXPR_INFO_ORDERBYNUM_C);
ins_num->type_enum = PT_TYPE_BIGINT;
ins_num->info.expr.op = PT_INST_NUM;
PT_EXPR_INFO_SET_FLAG (ins_num, PT_EXPR_INFO_INSTNUM_C);

ins_num->type_enum = PT_TYPE_BIGINT;
ins_num->info.expr.op = PT_INST_NUM;
PT_EXPR_INFO_SET_FLAG (ins_num, PT_EXPR_INFO_INSTNUM_C);
/* replace rownum of select-list to orderby_num */
statement->info.query.q.select.list =
pt_lambda_with_arg (parser, statement->info.query.q.select.list, ins_num, ord_num, false, 0, false);

/* replace rownum of where to orderby_num */
where = statement->info.query.q.select.where;
if (where != NULL && PT_EXPR_INFO_IS_FLAGED (where, PT_EXPR_INFO_ROWNUM_ONLY) && statement->info.query.order_by)
{
where = pt_lambda_with_arg (parser, where, ins_num, ord_num, false, 0, false);
statement->info.query.q.select.list =
pt_lambda_with_arg (parser, statement->info.query.q.select.list, ins_num, ord_num, false, 0, false);

/* move prev orderby_for to orderby_for */
prev_orderby_for = parser_copy_tree (parser, query_spec->info.query.orderby_for);
Expand Down Expand Up @@ -3911,25 +3920,15 @@ mq_is_rownum_only_predicate (PARSER_CONTEXT * parser, PT_NODE * spec, PT_NODE *
return false;
}

/* check if select list of mainquery has expr of instnum */
col = node->info.query.q.select.list;
while (col)
/* subquery check */
if (!pt_is_select (subquery))
{
/* cut off next */
save_next = col->next;
col->next = NULL;

if (!PT_IS_INSTNUM (col) && pt_has_inst_num (parser, col))
{
col->next = save_next;
return false;
}
col->next = save_next;
col = col->next;
return false;
}

/* subquery check */
if (!pt_is_select (subquery))
/* check if select list of mainquery has expr of instnum */
col = node->info.query.q.select.list;
if (pt_has_expr_of_inst_in_sel_list (parser, col))
{
return false;
}
Expand Down

0 comments on commit 3d20edf

Please sign in to comment.