Commit c8822d71 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10342 Providing compatibility for basic SQL built-in functions

Adding the Oracle style DECODE function:

  DECODE(operand, search, result [, search, result ...] [, default_result])
parent 02a72cf8
......@@ -346,3 +346,5 @@ CREATE TABLE raw (raw int);
DROP TABLE raw;
CREATE TABLE varchar2 (varchar2 int);
DROP TABLE varchar2;
CREATE TABLE decode (decode int);
DROP TABLE decode;
SET sql_mode=ORACLE;
SELECT DECODE(10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1
SELECT DECODE(10,10);
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1
SELECT DECODE(10,10,'x10');
DECODE(10,10,'x10')
x10
SELECT DECODE(11,10,'x10');
DECODE(11,10,'x10')
NULL
SELECT DECODE(10,10,'x10','def');
DECODE(10,10,'x10','def')
x10
SELECT DECODE(11,10,'x10','def');
DECODE(11,10,'x10','def')
def
SELECT DECODE(10,10,'x10',11,'x11','def');
DECODE(10,10,'x10',11,'x11','def')
x10
SELECT DECODE(11,10,'x10',11,'x11','def');
DECODE(11,10,'x10',11,'x11','def')
x11
SELECT DECODE(12,10,'x10',11,'x11','def');
DECODE(12,10,'x10',11,'x11','def')
def
EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select (case 12 when 10 then 'x10' when 11 then 'x11' else 'def' end) AS "DECODE(12,10,'x10',11,'x11','def')"
CREATE TABLE decode (decode int);
DROP TABLE decode;
SET sql_mode=ORACLE;
--error ER_PARSE_ERROR
SELECT DECODE(10);
--error ER_PARSE_ERROR
SELECT DECODE(10,10);
SELECT DECODE(10,10,'x10');
SELECT DECODE(11,10,'x10');
SELECT DECODE(10,10,'x10','def');
SELECT DECODE(11,10,'x10','def');
SELECT DECODE(10,10,'x10',11,'x11','def');
SELECT DECODE(11,10,'x10',11,'x11','def');
SELECT DECODE(12,10,'x10',11,'x11','def');
EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def');
CREATE TABLE decode (decode int);
DROP TABLE decode;
......@@ -241,3 +241,6 @@ DROP TABLE raw;
CREATE TABLE varchar2 (varchar2 int);
DROP TABLE varchar2;
CREATE TABLE decode (decode int);
DROP TABLE decode;
......@@ -882,19 +882,6 @@ class Create_func_dayofyear : public Create_func_arg1
};
class Create_func_decode : public Create_func_arg2
{
public:
virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2);
static Create_func_decode s_singleton;
protected:
Create_func_decode() {}
virtual ~Create_func_decode() {}
};
class Create_func_degrees : public Create_func_arg1
{
public:
......@@ -4067,15 +4054,6 @@ Create_func_dayofyear::create_1_arg(THD *thd, Item *arg1)
}
Create_func_decode Create_func_decode::s_singleton;
Item*
Create_func_decode::create_2_arg(THD *thd, Item *arg1, Item *arg2)
{
return new (thd->mem_root) Item_func_decode(thd, arg1, arg2);
}
Create_func_degrees Create_func_degrees::s_singleton;
Item*
......@@ -6772,7 +6750,6 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)},
{ { C_STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)},
{ { C_STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)},
{ { C_STRING_WITH_LEN("DECODE") }, BUILDER(Create_func_decode)},
{ { C_STRING_WITH_LEN("DEGREES") }, BUILDER(Create_func_degrees)},
{ { C_STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)},
{ { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
......
......@@ -705,6 +705,7 @@ static SYMBOL sql_functions[] = {
{ "CURTIME", SYM(CURTIME)},
{ "DATE_ADD", SYM(DATE_ADD_INTERVAL)},
{ "DATE_SUB", SYM(DATE_SUB_INTERVAL)},
{ "DECODE", SYM(DECODE_SYM)},
{ "DENSE_RANK", SYM(DENSE_RANK_SYM)},
{ "EXTRACT", SYM(EXTRACT_SYM)},
{ "FIRST_VALUE", SYM(FIRST_VALUE_SYM)},
......
......@@ -1041,6 +1041,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DECIMAL_NUM
%token DECIMAL_SYM /* SQL-2003-R */
%token DECLARE_SYM /* SQL-2003-R */
%token DECODE_SYM /* Oracle function, non-reserved */
%token DEFAULT /* SQL-2003-R */
%token DEFINER_SYM
%token DELAYED_SYM
......@@ -9370,6 +9371,12 @@ function_call_nonkeyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
| DECODE_SYM '(' expr ',' expr ')'
{
$$= new (thd->mem_root) Item_func_decode(thd, $3, $5);
if ($$ == NULL)
MYSQL_YYABORT;
}
| EXTRACT_SYM '(' interval FROM expr ')'
{
$$=new (thd->mem_root) Item_extract(thd, $3, $5);
......@@ -14279,6 +14286,7 @@ keyword_sp:
| DATETIME {}
| DATE_SYM {}
| DAY_SYM {}
| DECODE_SYM {}
| DEFINER_SYM {}
| DELAY_KEY_WRITE_SYM {}
| DES_KEY_FILE {}
......
......@@ -415,6 +415,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token DECIMAL_NUM
%token DECIMAL_SYM /* SQL-2003-R */
%token DECLARE_SYM /* SQL-2003-R */
%token DECODE_SYM /* Oracle function, non-reserved */
%token DEFAULT /* SQL-2003-R */
%token DEFINER_SYM
%token DELAYED_SYM
......@@ -1118,6 +1119,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <item_list>
expr_list opt_udf_expr_list udf_expr_list when_list
ident_list ident_list_arg opt_expr_list
decode_when_list
%type <var_type>
option_type opt_var_type opt_var_ident_type
......@@ -8850,6 +8852,36 @@ column_default_non_parenthesized_expr:
if ($$ == NULL)
MYSQL_YYABORT;
}
| DECODE_SYM '(' expr ',' decode_when_list ')'
{
if (($5->elements % 2) == 0)
{
// No default expression
$$= new (thd->mem_root) Item_func_case(thd, *$5, $3, NULL);
}
else
{
/*
There is a default expression at the end of the list $5.
Create a new list without the default expression.
*/
List<Item> tmp;
List_iterator_fast<Item> it(*$5);
for (uint i= 0; i < $5->elements - 1; i++) // copy all but last
{
Item *item= it++;
tmp.push_back(item);
}
/*
Now the new list "tmp" contains only WHEN-THEN pairs,
The default expression is pointed by the iterator "it"
and will be returned by the next call for it++ below.
*/
$$= new (thd->mem_root) Item_func_case(thd, tmp, $3, it++);
}
if ($$ == NULL)
MYSQL_YYABORT;
}
| DEFAULT '(' simple_ident ')'
{
Item_splocal *il= $3->get_item_splocal();
......@@ -10246,6 +10278,24 @@ when_list:
}
;
decode_when_list:
expr ',' expr
{
$$= new (thd->mem_root) List<Item>;
if ($$ == NULL)
MYSQL_YYABORT;
$$->push_back($1, thd->mem_root);
$$->push_back($3, thd->mem_root);
}
| decode_when_list ',' expr
{
$$= $1;
$$->push_back($3, thd->mem_root);
}
;
/* Equivalent to <table reference> in the SQL:2003 standard. */
/* Warning - may return NULL in case of incomplete SELECT */
table_ref:
......@@ -14190,6 +14240,7 @@ keyword_sp:
| DATETIME {}
| DATE_SYM {}
| DAY_SYM {}
| DECODE_SYM {}
| DEFINER_SYM {}
| DELAY_KEY_WRITE_SYM {}
| DES_KEY_FILE {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment