PL/SQL parser (MDEV-10142)

[MDEV-13864] Change Item_func_case to store the predicant in args[0] Created: 2017-09-22  Updated: 2020-08-25  Resolved: 2017-09-23

Status: Closed
Project: MariaDB Server
Component/s: OTHER
Affects Version/s: None
Fix Version/s: 10.3.2

Type: Technical task Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Blocks
blocks MDEV-13863 sql_mode=ORACLE: DECODE does not trea... Closed
Sprint: 10.2.2-3, 10.2.2-1, 10.2.2-2, 10.2.2-4, 10.1.18

 Description   

As of version 10.3.1, Item_func_case (when handling a simple CASE) stores the predicant argument (in the args[] array) after the WHEN..THEN arguments and before the ELSE argument.

For example, this expression:

CASE pred WHEN search1 THEN res1 WHEN search2 THEN res2 ELSE resE END

stores the arguments as follows:

  • args[0]=search1
  • args[1]=res1
  • args[2]=search2
  • args[3]=res2
  • args[4]=pred
  • args[6]=resE

Under terms of this task we'll do the following:
1. Change Item_func_case to store the arguments in the order of their appearance in the parser: the predicant argument in args[0], followed by the WHEN..THEN..ELSE arguments
2. Split Item_func_case into two separate classes Item_func_case_simple and Item_func_case_searched (for CASE expressions with and without predicant respectively).
3. Change the constructors of the affected classes just to accept a List<Item> argument (without additional first_expr_arg and else_expr_arg.

Advantages:

a. #1 and #3 will help to simplify the code in sql_yacc_ora.yy

| DECODE_SYM '(' expr ',' decode_when_list ')'
  {
    // 30 lines of the code, extracting {{else_expr_arg}} from the list.
  }

to something as simple as:

| DECODE_SYM '(' expr ',' decode_when_list ')'
  {
    $5->push_front($3, thd->mem_root);
    if (!($$= new (thd->mem_root) Item_func_case_simple(thd, *$5)))
      MYSQL_YYABORT;
  }

b. #1 and #3 will help to implement MDEV-13863 easier. MDEV-13836 will introduce a new class Item_func_decode_oracle. Without #1, we'd have to use the same complex code from sql_yacc_ora.yy, now for both DECODE() and DECODE_ORACLE().
c. #2 will slightly reduce the memory size required to handle searched CASE expression, because only Item_func_case_simple will need to derive from Predicant_to_list_comparator
d. #2 will make the code more readable by removing a lot of if statements like this:

if (first_expr_num != -1)
{
  ...
}
else
{
  ...
}

as the branches for the searched and the simple CASE expressions will reside in methods of different classes.
e. #1 will make it easier to debug the code in gdb, as printing the arguments in their syntactic order will be much easier than now.



 Comments   
Comment by Alexander Barkov [ 2017-09-23 ]

Pushed to bb-10.2-ext and 10.3

Generated at Thu Feb 08 08:08:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.