Commit 94ecd231 authored by halfspawn's avatar halfspawn Committed by Alexander Barkov

MDEV-15739 sql_mode=ORACLE: Make LPAD and RPAD return NULL instead of empty string

parent 1eee986e
SET sql_mode=ORACLE;
#
# MDEV-15739 - sql_mode=ORACLE: Make LPAD and RPAD return NULL instead of empty string
#
SELECT RPAD('a',0), RPAD('abc',1), RPAD('abc',2) ;
RPAD('a',0) RPAD('abc',1) RPAD('abc',2)
NULL a ab
SELECT RPAD('a',0,'.'), RPAD('abc',1,'.'), RPAD('abc',2,'.') ;
RPAD('a',0,'.') RPAD('abc',1,'.') RPAD('abc',2,'.')
NULL a ab
SELECT LPAD('a',0), LPAD('abc',1), LPAD('abc',2) ;
LPAD('a',0) LPAD('abc',1) LPAD('abc',2)
NULL a ab
SELECT LPAD('a',0,'.'), LPAD('abc',1,'.'), LPAD('abc',2,'.') ;
LPAD('a',0,'.') LPAD('abc',1,'.') LPAD('abc',2,'.')
NULL a ab
CREATE TABLE t1 (c1 VARCHAR(10),c2 INTEGER, c3 VARCHAR(10), ord INTEGER);
INSERT INTO t1 VALUES ('a',1,null,1);
INSERT INTO t1 VALUES ('a',null,'.',2);
INSERT INTO t1 VALUES (null,1,'.',3);
INSERT INTO t1 VALUES ('a',-1,'.',4);
INSERT INTO t1 VALUES ('a',0,'.',5);
INSERT INTO t1 VALUES ('a',1,'.',6);
INSERT INTO t1 VALUES ('a',2,'.',7);
SELECT LPAD(c1,c2,c3), LPAD(c1,c2) FROM t1 ORDER BY ord;
LPAD(c1,c2,c3) LPAD(c1,c2)
NULL a
NULL NULL
NULL NULL
NULL NULL
NULL NULL
a a
.a a
SELECT RPAD(c1,c2,c3), RPAD(c1,c2) FROM t1 ORDER BY ord;
RPAD(c1,c2,c3) RPAD(c1,c2)
NULL a
NULL NULL
NULL NULL
NULL NULL
NULL NULL
a a
a. a
EXPLAIN EXTENDED SELECT RPAD('a',0,'.'), LPAD('a',0,'.'), LPAD(c1,c2,c3), LPAD(c1,c2), RPAD(c1,c2,c3), RPAD(c1,c2) FROM t1 ORDER BY ord;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 Using filesort
Warnings:
Note 1003 select rpad_oracle('a',0,'.') AS "RPAD('a',0,'.')",lpad_oracle('a',0,'.') AS "LPAD('a',0,'.')",lpad_oracle("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "LPAD(c1,c2,c3)",lpad_oracle("test"."t1"."c1","test"."t1"."c2") AS "LPAD(c1,c2)",rpad_oracle("test"."t1"."c1","test"."t1"."c2","test"."t1"."c3") AS "RPAD(c1,c2,c3)",rpad_oracle("test"."t1"."c1","test"."t1"."c2") AS "RPAD(c1,c2)" from "test"."t1" order by "test"."t1"."ord"
CREATE VIEW v1 AS SELECT RPAD('a',0,'.') AS "C1", LPAD('a',0,'.') AS "C2", LPAD(c1,c2,c3) AS "C3", LPAD(c1,c2) AS "C4", RPAD(c1,c2,c3) AS "C5", RPAD(c1,c2) AS "C6" FROM t1 ORDER BY ord;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select rpad_oracle('a',0,'.') AS "C1",lpad_oracle('a',0,'.') AS "C2",lpad_oracle("t1"."c1","t1"."c2","t1"."c3") AS "C3",lpad_oracle("t1"."c1","t1"."c2") AS "C4",rpad_oracle("t1"."c1","t1"."c2","t1"."c3") AS "C5",rpad_oracle("t1"."c1","t1"."c2") AS "C6" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci
SELECT * FROM v1;
C1 C2 C3 C4 C5 C6
NULL NULL NULL a NULL a
NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
NULL NULL NULL NULL NULL NULL
NULL NULL a a a a
NULL NULL .a a a. a
SELECT c1||'-'||c2||'-'||c3||'-'||c4||'-'||c5||'-'||c6 FROM v1;
c1||'-'||c2||'-'||c3||'-'||c4||'-'||c5||'-'||c6
---a--a
-----
-----
-----
-----
--a-a-a-a
--.a- a-a.-a
DROP VIEW v1;
DROP TABLE t1;
SET sql_mode=ORACLE;
--echo #
--echo # MDEV-15739 - sql_mode=ORACLE: Make LPAD and RPAD return NULL instead of empty string
--echo #
SELECT RPAD('a',0), RPAD('abc',1), RPAD('abc',2) ;
SELECT RPAD('a',0,'.'), RPAD('abc',1,'.'), RPAD('abc',2,'.') ;
SELECT LPAD('a',0), LPAD('abc',1), LPAD('abc',2) ;
SELECT LPAD('a',0,'.'), LPAD('abc',1,'.'), LPAD('abc',2,'.') ;
CREATE TABLE t1 (c1 VARCHAR(10),c2 INTEGER, c3 VARCHAR(10), ord INTEGER);
INSERT INTO t1 VALUES ('a',1,null,1);
INSERT INTO t1 VALUES ('a',null,'.',2);
INSERT INTO t1 VALUES (null,1,'.',3);
INSERT INTO t1 VALUES ('a',-1,'.',4);
INSERT INTO t1 VALUES ('a',0,'.',5);
INSERT INTO t1 VALUES ('a',1,'.',6);
INSERT INTO t1 VALUES ('a',2,'.',7);
SELECT LPAD(c1,c2,c3), LPAD(c1,c2) FROM t1 ORDER BY ord;
SELECT RPAD(c1,c2,c3), RPAD(c1,c2) FROM t1 ORDER BY ord;
EXPLAIN EXTENDED SELECT RPAD('a',0,'.'), LPAD('a',0,'.'), LPAD(c1,c2,c3), LPAD(c1,c2), RPAD(c1,c2,c3), RPAD(c1,c2) FROM t1 ORDER BY ord;
CREATE VIEW v1 AS SELECT RPAD('a',0,'.') AS "C1", LPAD('a',0,'.') AS "C2", LPAD(c1,c2,c3) AS "C3", LPAD(c1,c2) AS "C4", RPAD(c1,c2,c3) AS "C5", RPAD(c1,c2) AS "C6" FROM t1 ORDER BY ord;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
SELECT c1||'-'||c2||'-'||c3||'-'||c4||'-'||c5||'-'||c6 FROM v1;
DROP VIEW v1;
DROP TABLE t1;
......@@ -2195,13 +2195,30 @@ class Create_func_lpad : public Create_native_func
{
public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name,
List<Item> *item_list);
List<Item> *item_list)
{
return thd->variables.sql_mode & MODE_ORACLE ?
create_native_oracle(thd, name, item_list) :
create_native_std(thd, name, item_list);
}
static Create_func_lpad s_singleton;
protected:
Create_func_lpad() {}
virtual ~Create_func_lpad() {}
Item *create_native_std(THD *thd, LEX_CSTRING *name, List<Item> *items);
Item *create_native_oracle(THD *thd, LEX_CSTRING *name, List<Item> *items);
};
class Create_func_lpad_oracle : public Create_func_lpad
{
public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
{
return create_native_oracle(thd, name, item_list);
}
static Create_func_lpad_oracle s_singleton;
};
......@@ -2648,13 +2665,30 @@ class Create_func_rpad : public Create_native_func
{
public:
virtual Item *create_native(THD *thd, LEX_CSTRING *name,
List<Item> *item_list);
List<Item> *item_list)
{
return thd->variables.sql_mode & MODE_ORACLE ?
create_native_oracle(thd, name, item_list) :
create_native_std(thd, name, item_list);
}
static Create_func_rpad s_singleton;
protected:
Create_func_rpad() {}
virtual ~Create_func_rpad() {}
Item *create_native_std(THD *thd, LEX_CSTRING *name, List<Item> *items);
Item *create_native_oracle(THD *thd, LEX_CSTRING *name, List<Item> *items);
};
class Create_func_rpad_oracle : public Create_func_rpad
{
public:
Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list)
{
return create_native_oracle(thd, name, item_list);
}
static Create_func_rpad_oracle s_singleton;
};
......@@ -5810,9 +5844,11 @@ Create_func_log2::create_1_arg(THD *thd, Item *arg1)
Create_func_lpad Create_func_lpad::s_singleton;
Create_func_lpad_oracle Create_func_lpad_oracle::s_singleton;
Item*
Create_func_lpad::create_native(THD *thd, LEX_CSTRING *name,
List<Item> *item_list)
Create_func_lpad::create_native_std(THD *thd, LEX_CSTRING *name,
List<Item> *item_list)
{
Item *func= NULL;
int arg_count= item_list ? item_list->elements : 0;
......@@ -5842,6 +5878,34 @@ Create_func_lpad::create_native(THD *thd, LEX_CSTRING *name,
}
Item*
Create_func_lpad::create_native_oracle(THD *thd, LEX_CSTRING *name,
List<Item> *item_list)
{
int arg_count= item_list ? item_list->elements : 0;
switch (arg_count) {
case 2:
{
Item *param_1= item_list->pop();
Item *param_2= item_list->pop();
return new (thd->mem_root) Item_func_lpad_oracle(thd, param_1, param_2);
}
case 3:
{
Item *param_1= item_list->pop();
Item *param_2= item_list->pop();
Item *param_3= item_list->pop();
return new (thd->mem_root) Item_func_lpad_oracle(thd, param_1,
param_2, param_3);
}
default:
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
break;
}
return NULL;
}
Create_func_ltrim Create_func_ltrim::s_singleton;
Item*
......@@ -6316,9 +6380,11 @@ Create_func_round::create_native(THD *thd, LEX_CSTRING *name,
Create_func_rpad Create_func_rpad::s_singleton;
Create_func_rpad_oracle Create_func_rpad_oracle::s_singleton;
Item*
Create_func_rpad::create_native(THD *thd, LEX_CSTRING *name,
List<Item> *item_list)
Create_func_rpad::create_native_std(THD *thd, LEX_CSTRING *name,
List<Item> *item_list)
{
Item *func= NULL;
int arg_count= item_list ? item_list->elements : 0;
......@@ -6348,6 +6414,34 @@ Create_func_rpad::create_native(THD *thd, LEX_CSTRING *name,
}
Item*
Create_func_rpad::create_native_oracle(THD *thd, LEX_CSTRING *name,
List<Item> *item_list)
{
int arg_count= item_list ? item_list->elements : 0;
switch (arg_count) {
case 2:
{
Item *param_1= item_list->pop();
Item *param_2= item_list->pop();
return new (thd->mem_root) Item_func_rpad_oracle(thd, param_1, param_2);
}
case 3:
{
Item *param_1= item_list->pop();
Item *param_2= item_list->pop();
Item *param_3= item_list->pop();
return new (thd->mem_root) Item_func_rpad_oracle(thd, param_1,
param_2, param_3);
}
default:
my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str);
break;
}
return NULL;
}
Create_func_rtrim Create_func_rtrim::s_singleton;
Item*
......@@ -7021,6 +7115,7 @@ static Native_func_registry func_array[] =
{ { STRING_WITH_LEN("LOG2") }, BUILDER(Create_func_log2)},
{ { STRING_WITH_LEN("LOWER") }, BUILDER(Create_func_lcase)},
{ { STRING_WITH_LEN("LPAD") }, BUILDER(Create_func_lpad)},
{ { STRING_WITH_LEN("LPAD_ORACLE") }, BUILDER(Create_func_lpad_oracle)},
{ { STRING_WITH_LEN("LTRIM") }, BUILDER(Create_func_ltrim)},
{ { STRING_WITH_LEN("LTRIM_ORACLE") }, BUILDER(Create_func_ltrim_oracle)},
{ { STRING_WITH_LEN("MAKEDATE") }, BUILDER(Create_func_makedate)},
......@@ -7086,6 +7181,7 @@ static Native_func_registry func_array[] =
{ { STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)},
{ { STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)},
{ { STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)},
{ { STRING_WITH_LEN("RPAD_ORACLE") }, BUILDER(Create_func_rpad_oracle)},
{ { STRING_WITH_LEN("RTRIM") }, BUILDER(Create_func_rtrim)},
{ { STRING_WITH_LEN("RTRIM_ORACLE") }, BUILDER(Create_func_rtrim_oracle)},
{ { STRING_WITH_LEN("SEC_TO_TIME") }, BUILDER(Create_func_sec_to_time)},
......
......@@ -1120,6 +1120,26 @@ class Item_func_rpad :public Item_func_pad
};
class Item_func_rpad_oracle :public Item_func_rpad
{
String *make_empty_result()
{ null_value= 1; return NULL; }
public:
Item_func_rpad_oracle(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_func_rpad(thd, arg1, arg2, arg3) {}
Item_func_rpad_oracle(THD *thd, Item *arg1, Item *arg2):
Item_func_rpad(thd, arg1, arg2) {}
void fix_length_and_dec()
{
Item_func_rpad::fix_length_and_dec();
maybe_null= true;
}
const char *func_name() const { return "rpad_oracle"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_rpad_oracle>(thd, this); }
};
class Item_func_lpad :public Item_func_pad
{
public:
......@@ -1134,6 +1154,26 @@ class Item_func_lpad :public Item_func_pad
};
class Item_func_lpad_oracle :public Item_func_lpad
{
String *make_empty_result()
{ null_value= 1; return NULL; }
public:
Item_func_lpad_oracle(THD *thd, Item *arg1, Item *arg2, Item *arg3):
Item_func_lpad(thd, arg1, arg2, arg3) {}
Item_func_lpad_oracle(THD *thd, Item *arg1, Item *arg2):
Item_func_lpad(thd, arg1, arg2) {}
void fix_length_and_dec()
{
Item_func_lpad::fix_length_and_dec();
maybe_null= true;
}
const char *func_name() const { return "lpad_oracle"; }
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_lpad_oracle>(thd, this); }
};
class Item_func_conv :public Item_str_func
{
public:
......
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