mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 04:22:27 +01:00
MDEV-10342 Providing compatibility for basic SQL built-in functions
Adding the Oracle style DECODE function: DECODE(operand, search, result [, search, result ...] [, default_result])
This commit is contained in:
parent
02a72cf87c
commit
c8822d71ef
8 changed files with 119 additions and 23 deletions
|
@ -346,3 +346,5 @@ CREATE TABLE raw (raw int);
|
||||||
DROP TABLE raw;
|
DROP TABLE raw;
|
||||||
CREATE TABLE varchar2 (varchar2 int);
|
CREATE TABLE varchar2 (varchar2 int);
|
||||||
DROP TABLE varchar2;
|
DROP TABLE varchar2;
|
||||||
|
CREATE TABLE decode (decode int);
|
||||||
|
DROP TABLE decode;
|
||||||
|
|
33
mysql-test/suite/compat/oracle/r/func_decode.result
Normal file
33
mysql-test/suite/compat/oracle/r/func_decode.result
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
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;
|
21
mysql-test/suite/compat/oracle/t/func_decode.test
Normal file
21
mysql-test/suite/compat/oracle/t/func_decode.test
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
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);
|
CREATE TABLE varchar2 (varchar2 int);
|
||||||
DROP TABLE varchar2;
|
DROP TABLE varchar2;
|
||||||
|
|
||||||
|
CREATE TABLE decode (decode int);
|
||||||
|
DROP TABLE decode;
|
||||||
|
|
|
@ -882,19 +882,6 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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
|
class Create_func_degrees : public Create_func_arg1
|
||||||
{
|
{
|
||||||
public:
|
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;
|
Create_func_degrees Create_func_degrees::s_singleton;
|
||||||
|
|
||||||
Item*
|
Item*
|
||||||
|
@ -6772,7 +6750,6 @@ static Native_func_registry func_array[] =
|
||||||
{ { C_STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)},
|
{ { C_STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)},
|
||||||
{ { C_STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)},
|
{ { C_STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)},
|
||||||
{ { C_STRING_WITH_LEN("DAYOFYEAR") }, BUILDER(Create_func_dayofyear)},
|
{ { 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("DEGREES") }, BUILDER(Create_func_degrees)},
|
||||||
{ { C_STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)},
|
{ { C_STRING_WITH_LEN("DECODE_HISTOGRAM") }, BUILDER(Create_func_decode_histogram)},
|
||||||
{ { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
|
{ { C_STRING_WITH_LEN("DES_DECRYPT") }, BUILDER(Create_func_des_decrypt)},
|
||||||
|
|
|
@ -705,6 +705,7 @@ static SYMBOL sql_functions[] = {
|
||||||
{ "CURTIME", SYM(CURTIME)},
|
{ "CURTIME", SYM(CURTIME)},
|
||||||
{ "DATE_ADD", SYM(DATE_ADD_INTERVAL)},
|
{ "DATE_ADD", SYM(DATE_ADD_INTERVAL)},
|
||||||
{ "DATE_SUB", SYM(DATE_SUB_INTERVAL)},
|
{ "DATE_SUB", SYM(DATE_SUB_INTERVAL)},
|
||||||
|
{ "DECODE", SYM(DECODE_SYM)},
|
||||||
{ "DENSE_RANK", SYM(DENSE_RANK_SYM)},
|
{ "DENSE_RANK", SYM(DENSE_RANK_SYM)},
|
||||||
{ "EXTRACT", SYM(EXTRACT_SYM)},
|
{ "EXTRACT", SYM(EXTRACT_SYM)},
|
||||||
{ "FIRST_VALUE", SYM(FIRST_VALUE_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_NUM
|
||||||
%token DECIMAL_SYM /* SQL-2003-R */
|
%token DECIMAL_SYM /* SQL-2003-R */
|
||||||
%token DECLARE_SYM /* SQL-2003-R */
|
%token DECLARE_SYM /* SQL-2003-R */
|
||||||
|
%token DECODE_SYM /* Oracle function, non-reserved */
|
||||||
%token DEFAULT /* SQL-2003-R */
|
%token DEFAULT /* SQL-2003-R */
|
||||||
%token DEFINER_SYM
|
%token DEFINER_SYM
|
||||||
%token DELAYED_SYM
|
%token DELAYED_SYM
|
||||||
|
@ -9370,6 +9371,12 @@ function_call_nonkeyword:
|
||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
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 ')'
|
| EXTRACT_SYM '(' interval FROM expr ')'
|
||||||
{
|
{
|
||||||
$$=new (thd->mem_root) Item_extract(thd, $3, $5);
|
$$=new (thd->mem_root) Item_extract(thd, $3, $5);
|
||||||
|
@ -14279,6 +14286,7 @@ keyword_sp:
|
||||||
| DATETIME {}
|
| DATETIME {}
|
||||||
| DATE_SYM {}
|
| DATE_SYM {}
|
||||||
| DAY_SYM {}
|
| DAY_SYM {}
|
||||||
|
| DECODE_SYM {}
|
||||||
| DEFINER_SYM {}
|
| DEFINER_SYM {}
|
||||||
| DELAY_KEY_WRITE_SYM {}
|
| DELAY_KEY_WRITE_SYM {}
|
||||||
| DES_KEY_FILE {}
|
| DES_KEY_FILE {}
|
||||||
|
|
|
@ -415,6 +415,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%token DECIMAL_NUM
|
%token DECIMAL_NUM
|
||||||
%token DECIMAL_SYM /* SQL-2003-R */
|
%token DECIMAL_SYM /* SQL-2003-R */
|
||||||
%token DECLARE_SYM /* SQL-2003-R */
|
%token DECLARE_SYM /* SQL-2003-R */
|
||||||
|
%token DECODE_SYM /* Oracle function, non-reserved */
|
||||||
%token DEFAULT /* SQL-2003-R */
|
%token DEFAULT /* SQL-2003-R */
|
||||||
%token DEFINER_SYM
|
%token DEFINER_SYM
|
||||||
%token DELAYED_SYM
|
%token DELAYED_SYM
|
||||||
|
@ -1118,6 +1119,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
||||||
%type <item_list>
|
%type <item_list>
|
||||||
expr_list opt_udf_expr_list udf_expr_list when_list
|
expr_list opt_udf_expr_list udf_expr_list when_list
|
||||||
ident_list ident_list_arg opt_expr_list
|
ident_list ident_list_arg opt_expr_list
|
||||||
|
decode_when_list
|
||||||
|
|
||||||
%type <var_type>
|
%type <var_type>
|
||||||
option_type opt_var_type opt_var_ident_type
|
option_type opt_var_type opt_var_ident_type
|
||||||
|
@ -8850,6 +8852,36 @@ column_default_non_parenthesized_expr:
|
||||||
if ($$ == NULL)
|
if ($$ == NULL)
|
||||||
MYSQL_YYABORT;
|
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 ')'
|
| DEFAULT '(' simple_ident ')'
|
||||||
{
|
{
|
||||||
Item_splocal *il= $3->get_item_splocal();
|
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. */
|
/* Equivalent to <table reference> in the SQL:2003 standard. */
|
||||||
/* Warning - may return NULL in case of incomplete SELECT */
|
/* Warning - may return NULL in case of incomplete SELECT */
|
||||||
table_ref:
|
table_ref:
|
||||||
|
@ -14190,6 +14240,7 @@ keyword_sp:
|
||||||
| DATETIME {}
|
| DATETIME {}
|
||||||
| DATE_SYM {}
|
| DATE_SYM {}
|
||||||
| DAY_SYM {}
|
| DAY_SYM {}
|
||||||
|
| DECODE_SYM {}
|
||||||
| DEFINER_SYM {}
|
| DEFINER_SYM {}
|
||||||
| DELAY_KEY_WRITE_SYM {}
|
| DELAY_KEY_WRITE_SYM {}
|
||||||
| DES_KEY_FILE {}
|
| DES_KEY_FILE {}
|
||||||
|
|
Loading…
Reference in a new issue