1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-06-15 03:21:42 +03:00

MCOL-4044: Add oracle mode functions.

This commit is contained in:
benthompson15
2021-04-21 16:07:42 -05:00
parent 1f46baa980
commit 870d672efb
20 changed files with 2624 additions and 0 deletions

View File

@ -0,0 +1,389 @@
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
EXPLAIN EXTENDED SELECT 'a'||'b'||'c';
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 concat_operator_oracle(concat_operator_oracle('a','b'),'c') AS "'a'||'b'||'c'"
EXPLAIN EXTENDED SELECT CONCAT('a'||'b'||'c');
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 concat_operator_oracle(concat_operator_oracle(concat_operator_oracle('a','b'),'c')) AS "CONCAT('a'||'b'||'c')"
SELECT '' || '';
'' || ''
SELECT '' || 'b';
'' || 'b'
b
SELECT '' || NULL;
'' || NULL
SELECT 'a' || '';
'a' || ''
a
SELECT 'a' || 'b';
'a' || 'b'
ab
SELECT 'a' || NULL;
'a' || NULL
a
SELECT NULL || '';
NULL || ''
SELECT NULL || 'b';
NULL || 'b'
b
SELECT NULL || NULL;
NULL || NULL
NULL
SELECT '' || '' || '';
'' || '' || ''
SELECT '' || '' || 'c';
'' || '' || 'c'
c
SELECT '' || '' || NULL;
'' || '' || NULL
SELECT '' || 'b' || '';
'' || 'b' || ''
b
SELECT '' || 'b' || 'c';
'' || 'b' || 'c'
bc
SELECT '' || 'b' || NULL;
'' || 'b' || NULL
b
SELECT '' || NULL || '';
'' || NULL || ''
SELECT '' || NULL || 'c';
'' || NULL || 'c'
c
SELECT '' || NULL || NULL;
'' || NULL || NULL
SELECT 'a' || '' || '';
'a' || '' || ''
a
SELECT 'a' || '' || 'c';
'a' || '' || 'c'
ac
SELECT 'a' || '' || NULL;
'a' || '' || NULL
a
SELECT 'a' || 'b' || '';
'a' || 'b' || ''
ab
SELECT 'a' || 'b' || 'c';
'a' || 'b' || 'c'
abc
SELECT 'a' || 'b' || NULL;
'a' || 'b' || NULL
ab
SELECT 'a' || NULL || '';
'a' || NULL || ''
a
SELECT 'a' || NULL || 'c';
'a' || NULL || 'c'
ac
SELECT 'a' || NULL || NULL;
'a' || NULL || NULL
a
SELECT NULL || '' || '';
NULL || '' || ''
SELECT NULL || '' || 'c';
NULL || '' || 'c'
c
SELECT NULL || '' || NULL;
NULL || '' || NULL
SELECT NULL || 'b' || '';
NULL || 'b' || ''
b
SELECT NULL || 'b' || 'c';
NULL || 'b' || 'c'
bc
SELECT NULL || 'b' || NULL;
NULL || 'b' || NULL
b
SELECT NULL || NULL || '';
NULL || NULL || ''
SELECT NULL || NULL || 'c';
NULL || NULL || 'c'
c
SELECT NULL || NULL || NULL;
NULL || NULL || NULL
NULL
CREATE TABLE t1 (a VARCHAR(10), b VARCHAR(10), c VARCHAR(10));
INSERT INTO t1 VALUES ('', '', '');
INSERT INTO t1 VALUES ('', '', 'c');
INSERT INTO t1 VALUES ('', '', NULL);
INSERT INTO t1 VALUES ('', 'b', '');
INSERT INTO t1 VALUES ('', 'b', 'c');
INSERT INTO t1 VALUES ('', 'b', NULL);
INSERT INTO t1 VALUES ('', NULL, '');
INSERT INTO t1 VALUES ('', NULL, 'c');
INSERT INTO t1 VALUES ('', NULL, NULL);
INSERT INTO t1 VALUES ('a', '', '');
INSERT INTO t1 VALUES ('a', '', 'c');
INSERT INTO t1 VALUES ('a', '', NULL);
INSERT INTO t1 VALUES ('a', 'b', '');
INSERT INTO t1 VALUES ('a', 'b', 'c');
INSERT INTO t1 VALUES ('a', 'b', NULL);
INSERT INTO t1 VALUES ('a', NULL, '');
INSERT INTO t1 VALUES ('a', NULL, 'c');
INSERT INTO t1 VALUES ('a', NULL, NULL);
INSERT INTO t1 VALUES (NULL, '', '');
INSERT INTO t1 VALUES (NULL, '', 'c');
INSERT INTO t1 VALUES (NULL, '', NULL);
INSERT INTO t1 VALUES (NULL, 'b', '');
INSERT INTO t1 VALUES (NULL, 'b', 'c');
INSERT INTO t1 VALUES (NULL, 'b', NULL);
INSERT INTO t1 VALUES (NULL, NULL, '');
INSERT INTO t1 VALUES (NULL, NULL, 'c');
INSERT INTO t1 VALUES (NULL, NULL, NULL);
SELECT LENGTH(a||b||c), a||b||c FROM t1 ORDER BY a,b,c;
LENGTH(a||b||c) a||b||c
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
1 c
1 c
1 c
1 c
1 b
1 b
1 b
1 b
2 bc
2 bc
1 a
1 a
1 a
1 a
2 ac
2 ac
2 ab
2 ab
3 abc
SELECT LENGTH(CONCAT(a||b||c)), CONCAT(a||b||c) FROM t1 ORDER BY a,b,c;
LENGTH(CONCAT(a||b||c)) CONCAT(a||b||c)
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
0 NULL
1 c
1 c
1 c
1 c
1 b
1 b
1 b
1 b
2 bc
2 bc
1 a
1 a
1 a
1 a
2 ac
2 ac
2 ab
2 ab
3 abc
DROP TABLE t1;
#
# MDEV-12478 CONCAT function inside view casts values incorrectly with Oracle sql_mode
#
SET sql_mode=ORACLE;
CREATE VIEW v1 AS SELECT 'foo'||NULL||'bar' AS test;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select concat_operator_oracle(concat_operator_oracle('foo',NULL),'bar') AS "test" latin1 latin1_swedish_ci
SELECT * FROM v1;
test
foobar
SET sql_mode=DEFAULT;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select concat_operator_oracle(concat_operator_oracle('foo',NULL),'bar') AS `test` latin1 latin1_swedish_ci
SELECT * FROM v1;
test
foobar
DROP VIEW v1;
SET sql_mode=DEFAULT;
CREATE VIEW v1 AS SELECT CONCAT('foo',NULL,'bar') AS test;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select concat('foo',NULL,'bar') AS `test` latin1 latin1_swedish_ci
SELECT * FROM v1;
test
NULL
SET sql_mode=ORACLE;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select concat('foo',NULL,'bar') AS "test" latin1 latin1_swedish_ci
SELECT * FROM v1;
test
NULL
DROP VIEW v1;
SET sql_mode=DEFAULT;
CREATE VIEW v1 AS SELECT '0'||'1' AS test;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select '0' or '1' AS `test` latin1 latin1_swedish_ci
SELECT * FROM v1;
test
1
SET sql_mode=ORACLE;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select '0' or '1' AS "test" latin1 latin1_swedish_ci
SELECT * FROM v1;
test
1
DROP VIEW v1;
#
# MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE
#
SELECT -1<<1||1 AS a FROM DUAL;
a
18446744073709549568
SELECT -1||0<<1 AS a FROM DUAL;
a
18446744073709551596
EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL;
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 -1 << concat_operator_oracle(1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL;
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 concat_operator_oracle(-1,0) << 1 AS "a"
SELECT -1+1||1 AS a FROM DUAL;
a
01
SELECT -1||0+1 AS a FROM DUAL;
a
-9
EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL;
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 concat_operator_oracle(-1 + 1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL;
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 concat_operator_oracle(-1,0) + 1 AS "a"
SELECT 1*1||-1 AS a FROM DUAL;
a
1-1
SELECT 1||1*-1 AS a FROM DUAL;
a
1-1
EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL;
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 concat_operator_oracle(1 * 1,-1) AS "a"
EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL;
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 concat_operator_oracle(1,1 * -1) AS "a"
SELECT -1^1||1 AS a FROM DUAL;
a
184467440737095516141
SELECT -1||0^1 AS a FROM DUAL;
a
-11
EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL;
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 concat_operator_oracle(-1 ^ 1,1) AS "a"
EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL;
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 concat_operator_oracle(-1,0 ^ 1) AS "a"
#
# MDEV-17359 Concatenation operator || in like expression failed in sql_mode=ORACLE
#
SELECT 'abc' LIKE 'a'||'%';
'abc' LIKE 'a'||'%'
1
EXPLAIN EXTENDED SELECT 'abc' LIKE 'a'||'%';
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 'abc' like concat_operator_oracle('a','%') AS "'abc' LIKE 'a'||'%'"
SELECT 'x' FROM DUAL WHERE 11 LIKE 1||1;
x
x
SELECT 'x' FROM DUAL WHERE 1||1 LIKE 11;
x
x
SELECT 'x' FROM DUAL WHERE 1||1 LIKE 1||1;
x
x
CREATE TABLE t1 (c1 VARCHAR(10),c2 VARCHAR(10), ord INTEGER);
INSERT INTO t1 VALUES ('a', 'ab' ,1);
INSERT INTO t1 VALUES ('ab', 'ab', 2);
INSERT INTO t1 VALUES ('abc', 'ab', 3);
SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord;
c1
ab
EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" USE INDEX () where "test"."t1"."c1" like concat_operator_oracle('%','b') order by "test"."t1"."ord"
SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord;
c1
abc
EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 select "test"."t1"."c1" AS "c1" from "test"."t1" USE INDEX () where "test"."t1"."c1" like concat_operator_oracle(concat_operator_oracle("test"."t1"."c2",'%'),'c') order by "test"."t1"."ord"
SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%';
x
x
EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 select 'x' AS "x" from "test"."t1" USE INDEX () where concat_operator_oracle("test"."t1"."c1","test"."t1"."c2") like 'aa%'
SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1;
x
x
EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 select 'x' AS "x" from "test"."t1" USE INDEX () where concat_operator_oracle("test"."t1"."c1","test"."t1"."c2") like concat_operator_oracle("test"."t1"."c2","test"."t1"."c1")
CREATE VIEW v1 AS SELECT c1, c2, c1 LIKE c2||'_' FROM t1 ORDER BY ord;
EXPLAIN EXTENDED SELECT * FROM v1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PUSHED SELECT NULL NULL NULL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1003 select "test"."t1"."c1" AS "c1","test"."t1"."c2" AS "c2","test"."t1"."c1" like concat_operator_oracle("test"."t1"."c2",'_') AS "c1 LIKE c2||'_'" from "test"."t1" USE INDEX () order by "test"."t1"."ord"
DROP VIEW v1;
DROP TABLE t1;

View File

@ -0,0 +1,189 @@
#
# Testing CONCAT with null values
#
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
EXPLAIN EXTENDED SELECT 'a'||'b'||'c';
EXPLAIN EXTENDED SELECT CONCAT('a'||'b'||'c');
SELECT '' || '';
SELECT '' || 'b';
SELECT '' || NULL;
SELECT 'a' || '';
SELECT 'a' || 'b';
SELECT 'a' || NULL;
SELECT NULL || '';
SELECT NULL || 'b';
SELECT NULL || NULL;
SELECT '' || '' || '';
SELECT '' || '' || 'c';
SELECT '' || '' || NULL;
SELECT '' || 'b' || '';
SELECT '' || 'b' || 'c';
SELECT '' || 'b' || NULL;
SELECT '' || NULL || '';
SELECT '' || NULL || 'c';
SELECT '' || NULL || NULL;
SELECT 'a' || '' || '';
SELECT 'a' || '' || 'c';
SELECT 'a' || '' || NULL;
SELECT 'a' || 'b' || '';
SELECT 'a' || 'b' || 'c';
SELECT 'a' || 'b' || NULL;
SELECT 'a' || NULL || '';
SELECT 'a' || NULL || 'c';
SELECT 'a' || NULL || NULL;
SELECT NULL || '' || '';
SELECT NULL || '' || 'c';
SELECT NULL || '' || NULL;
SELECT NULL || 'b' || '';
SELECT NULL || 'b' || 'c';
SELECT NULL || 'b' || NULL;
SELECT NULL || NULL || '';
SELECT NULL || NULL || 'c';
SELECT NULL || NULL || NULL;
CREATE TABLE t1 (a VARCHAR(10), b VARCHAR(10), c VARCHAR(10));
INSERT INTO t1 VALUES ('', '', '');
INSERT INTO t1 VALUES ('', '', 'c');
INSERT INTO t1 VALUES ('', '', NULL);
INSERT INTO t1 VALUES ('', 'b', '');
INSERT INTO t1 VALUES ('', 'b', 'c');
INSERT INTO t1 VALUES ('', 'b', NULL);
INSERT INTO t1 VALUES ('', NULL, '');
INSERT INTO t1 VALUES ('', NULL, 'c');
INSERT INTO t1 VALUES ('', NULL, NULL);
INSERT INTO t1 VALUES ('a', '', '');
INSERT INTO t1 VALUES ('a', '', 'c');
INSERT INTO t1 VALUES ('a', '', NULL);
INSERT INTO t1 VALUES ('a', 'b', '');
INSERT INTO t1 VALUES ('a', 'b', 'c');
INSERT INTO t1 VALUES ('a', 'b', NULL);
INSERT INTO t1 VALUES ('a', NULL, '');
INSERT INTO t1 VALUES ('a', NULL, 'c');
INSERT INTO t1 VALUES ('a', NULL, NULL);
INSERT INTO t1 VALUES (NULL, '', '');
INSERT INTO t1 VALUES (NULL, '', 'c');
INSERT INTO t1 VALUES (NULL, '', NULL);
INSERT INTO t1 VALUES (NULL, 'b', '');
INSERT INTO t1 VALUES (NULL, 'b', 'c');
INSERT INTO t1 VALUES (NULL, 'b', NULL);
INSERT INTO t1 VALUES (NULL, NULL, '');
INSERT INTO t1 VALUES (NULL, NULL, 'c');
INSERT INTO t1 VALUES (NULL, NULL, NULL);
SELECT LENGTH(a||b||c), a||b||c FROM t1 ORDER BY a,b,c;
SELECT LENGTH(CONCAT(a||b||c)), CONCAT(a||b||c) FROM t1 ORDER BY a,b,c;
DROP TABLE t1;
--echo #
--echo # MDEV-12478 CONCAT function inside view casts values incorrectly with Oracle sql_mode
--echo #
SET sql_mode=ORACLE;
CREATE VIEW v1 AS SELECT 'foo'||NULL||'bar' AS test;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
SET sql_mode=DEFAULT;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
SET sql_mode=DEFAULT;
CREATE VIEW v1 AS SELECT CONCAT('foo',NULL,'bar') AS test;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
SET sql_mode=ORACLE;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
SET sql_mode=DEFAULT;
CREATE VIEW v1 AS SELECT '0'||'1' AS test;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
SET sql_mode=ORACLE;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
--echo #
--echo # MDEV-16186 Concatenation operator || returns wrong results in sql_mode=ORACLE
--echo #
# Concatenation operator || has the same precedence with +
# (stronger than << and weaker than * ^)
SELECT -1<<1||1 AS a FROM DUAL;
SELECT -1||0<<1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1<<1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0<<1 AS a FROM DUAL;
SELECT -1+1||1 AS a FROM DUAL;
SELECT -1||0+1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1+1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0+1 AS a FROM DUAL;
SELECT 1*1||-1 AS a FROM DUAL;
SELECT 1||1*-1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT 1*1||-1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT 1||1*-1 AS a FROM DUAL;
SELECT -1^1||1 AS a FROM DUAL;
SELECT -1||0^1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1^1||1 AS a FROM DUAL;
EXPLAIN EXTENDED SELECT -1||0^1 AS a FROM DUAL;
--echo #
--echo # MDEV-17359 Concatenation operator || in like expression failed in sql_mode=ORACLE
--echo #
SELECT 'abc' LIKE 'a'||'%';
EXPLAIN EXTENDED SELECT 'abc' LIKE 'a'||'%';
SELECT 'x' FROM DUAL WHERE 11 LIKE 1||1;
SELECT 'x' FROM DUAL WHERE 1||1 LIKE 11;
SELECT 'x' FROM DUAL WHERE 1||1 LIKE 1||1;
CREATE TABLE t1 (c1 VARCHAR(10),c2 VARCHAR(10), ord INTEGER);
INSERT INTO t1 VALUES ('a', 'ab' ,1);
INSERT INTO t1 VALUES ('ab', 'ab', 2);
INSERT INTO t1 VALUES ('abc', 'ab', 3);
SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord;
EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE '%'||'b' ORDER BY ord;
SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord;
EXPLAIN EXTENDED SELECT c1 FROM t1 WHERE c1 LIKE c2||'%'||'c' ORDER BY ord;
SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%';
EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE 'aa%';
SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1;
EXPLAIN EXTENDED SELECT 'x' FROM t1 WHERE c1||c2 LIKE c2||c1;
CREATE VIEW v1 AS SELECT c1, c2, c1 LIKE c2||'_' FROM t1 ORDER BY ord;
EXPLAIN EXTENDED SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;

View File

@ -0,0 +1,171 @@
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
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 decode_oracle(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')"
CREATE TABLE decode (decode int);
DROP TABLE decode;
#
# MDEV-13863 sql_mode=ORACLE: DECODE does not treat two NULLs as equivalent
#
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_ORACLE(10);
ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE'
SELECT DECODE_ORACLE(10,10);
ERROR 42000: Incorrect parameter count in the call to native function 'DECODE_ORACLE'
EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11');
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 decode_oracle(12,10,'x10',11,'x11') AS "DECODE(12,10,'x10',11,'x11')"
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 decode_oracle(12,10,'x10',11,'x11','def') AS "DECODE(12,10,'x10',11,'x11','def')"
EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11');
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 decode_oracle(12,10,'x10',11,'x11') AS "DECODE_ORACLE(12,10,'x10',11,'x11')"
EXPLAIN EXTENDED SELECT DECODE_ORACLE(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 decode_oracle(12,10,'x10',11,'x11','def') AS "DECODE_ORACLE(12,10,'x10',11,'x11','def')"
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS
SELECT
DECODE(a,1,'x1',NULL,'xNULL') AS d1,
DECODE(a,1,'x1',NULL,'xNULL','xELSE') AS d2,
DECODE_ORACLE(a,1,'x1',NULL,'xNULL') AS d3,
DECODE_ORACLE(a,1,'x1',NULL,'xNULL','xELSE') AS d4
FROM t1;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select decode_oracle("t1"."a",1,'x1',NULL,'xNULL') AS "d1",decode_oracle("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d2",decode_oracle("t1"."a",1,'x1',NULL,'xNULL') AS "d3",decode_oracle("t1"."a",1,'x1',NULL,'xNULL','xELSE') AS "d4" from "t1" latin1 latin1_swedish_ci
DROP VIEW v1;
DROP TABLE t1;
SELECT DECODE(TIME'10:20:31','10:20:31','then1','10:20:32','then2','def');
DECODE(TIME'10:20:31','10:20:31','then1','10:20:32','then2','def')
then1
SELECT DECODE(TIME'10:20:32','10:20:31','then1','10:20:32','then2','def');
DECODE(TIME'10:20:32','10:20:31','then1','10:20:32','then2','def')
then2
SELECT DECODE(TIME'10:20:33','10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def');
DECODE(TIME'10:20:33','10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def')
then3
SELECT DECODE(NULL,TIME'10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def');
DECODE(NULL,TIME'10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def')
then2NULL
SELECT DECODE(TIMESTAMP'2001-01-01 10:20:31','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def');
DECODE(TIMESTAMP'2001-01-01 10:20:31','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def')
then1
SELECT DECODE(TIMESTAMP'2001-01-01 10:20:32','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def');
DECODE(TIMESTAMP'2001-01-01 10:20:32','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def')
then2
SELECT DECODE(TIMESTAMP'2001-01-01 10:20:33','2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def');
DECODE(TIMESTAMP'2001-01-01 10:20:33','2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def')
then3
SELECT DECODE(NULL,TIMESTAMP'2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def');
DECODE(NULL,TIMESTAMP'2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def')
then2NULL
SELECT DECODE('w1','w1','then1','w2','then2','def');
DECODE('w1','w1','then1','w2','then2','def')
then1
SELECT DECODE('w2','w1','then1','w2','then2','def');
DECODE('w2','w1','then1','w2','then2','def')
then2
SELECT DECODE('w3','w1','then1',NULL,'then2NULL','w3','then3','def');
DECODE('w3','w1','then1',NULL,'then2NULL','w3','then3','def')
then3
SELECT DECODE(NULL,'w1','then1',NULL,'then2NULL','w3','then3','def');
DECODE(NULL,'w1','then1',NULL,'then2NULL','w3','then3','def')
then2NULL
SELECT DECODE(1,1,'then1',2,'then2','def');
DECODE(1,1,'then1',2,'then2','def')
then1
SELECT DECODE(2,1,'then1',2,'then2','def');
DECODE(2,1,'then1',2,'then2','def')
then2
SELECT DECODE(3,1,'then1',NULL,'then2NULL',3,'then3','def');
DECODE(3,1,'then1',NULL,'then2NULL',3,'then3','def')
then3
SELECT DECODE(NULL,1,'then1',NULL,'then2NULL',3,'then3','def');
DECODE(NULL,1,'then1',NULL,'then2NULL',3,'then3','def')
then2NULL
SELECT DECODE(CAST(NULL AS SIGNED),1,'then1',NULL,'then2NULL',3,'then3','def');
DECODE(CAST(NULL AS SIGNED),1,'then1',NULL,'then2NULL',3,'then3','def')
then2NULL
SELECT DECODE(1.0,1.0,'then1',2.0,'then2','def');
DECODE(1.0,1.0,'then1',2.0,'then2','def')
then1
SELECT DECODE(2.0,1.0,'then1',2.0,'then2','def');
DECODE(2.0,1.0,'then1',2.0,'then2','def')
then2
SELECT DECODE(3.0,1.0,'then1',NULL,'then2NULL',3.0,'then3','def');
DECODE(3.0,1.0,'then1',NULL,'then2NULL',3.0,'then3','def')
then3
SELECT DECODE(NULL,1.0,'then1',NULL,'then2NULL',3.0,'then3','def');
DECODE(NULL,1.0,'then1',NULL,'then2NULL',3.0,'then3','def')
then2NULL
SELECT DECODE(CAST(NULL AS DECIMAL),1.0,'then1',NULL,'then2NULL',3.0,'then3','def');
DECODE(CAST(NULL AS DECIMAL),1.0,'then1',NULL,'then2NULL',3.0,'then3','def')
then2NULL
SELECT DECODE(1e0,1e0,'then1',2e0,'then2','def');
DECODE(1e0,1e0,'then1',2e0,'then2','def')
then1
SELECT DECODE(2e0,1e0,'then1',2e0,'then2','def');
DECODE(2e0,1e0,'then1',2e0,'then2','def')
then2
SELECT DECODE(3e0,1e0,'then1',NULL,'then2NULL',3e0,'then3','def');
DECODE(3e0,1e0,'then1',NULL,'then2NULL',3e0,'then3','def')
then3
SELECT DECODE(NULL,1e0,'then1',NULL,'then2NULL',3e0,'then3','def');
DECODE(NULL,1e0,'then1',NULL,'then2NULL',3e0,'then3','def')
then2NULL
SELECT DECODE(CAST(NULL AS DOUBLE),1e0,'then1',NULL,'then2NULL',3e0,'then3','def');
DECODE(CAST(NULL AS DOUBLE),1e0,'then1',NULL,'then2NULL',3e0,'then3','def')
then2NULL
SELECT DECODE(NULL,NULL,1,2) FROM DUAL;
DECODE(NULL,NULL,1,2)
1
SELECT DECODE(NULL,10,10,NULL,1,2) FROM DUAL;
DECODE(NULL,10,10,NULL,1,2)
1
SELECT DECODE_ORACLE(NULL,NULL,1,2) FROM DUAL;
DECODE_ORACLE(NULL,NULL,1,2)
1
SELECT DECODE_ORACLE(NULL,10,10,NULL,1,2) FROM DUAL;
DECODE_ORACLE(NULL,10,10,NULL,1,2)
1

View File

@ -0,0 +1,94 @@
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
--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;
--echo #
--echo # MDEV-13863 sql_mode=ORACLE: DECODE does not treat two NULLs as equivalent
--echo #
--error ER_PARSE_ERROR
SELECT DECODE(10);
--error ER_PARSE_ERROR
SELECT DECODE(10,10);
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT DECODE_ORACLE(10);
--error ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT
SELECT DECODE_ORACLE(10,10);
EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11');
EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def');
EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11');
EXPLAIN EXTENDED SELECT DECODE_ORACLE(12,10,'x10',11,'x11','def');
CREATE TABLE t1 (a INT);
CREATE VIEW v1 AS
SELECT
DECODE(a,1,'x1',NULL,'xNULL') AS d1,
DECODE(a,1,'x1',NULL,'xNULL','xELSE') AS d2,
DECODE_ORACLE(a,1,'x1',NULL,'xNULL') AS d3,
DECODE_ORACLE(a,1,'x1',NULL,'xNULL','xELSE') AS d4
FROM t1;
SHOW CREATE VIEW v1;
DROP VIEW v1;
DROP TABLE t1;
SELECT DECODE(TIME'10:20:31','10:20:31','then1','10:20:32','then2','def');
SELECT DECODE(TIME'10:20:32','10:20:31','then1','10:20:32','then2','def');
SELECT DECODE(TIME'10:20:33','10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def');
SELECT DECODE(NULL,TIME'10:20:31','then1',NULL,'then2NULL','10:20:33','then3','def');
SELECT DECODE(TIMESTAMP'2001-01-01 10:20:31','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def');
SELECT DECODE(TIMESTAMP'2001-01-01 10:20:32','2001-01-01 10:20:31','then1','2001-01-01 10:20:32','then2','def');
SELECT DECODE(TIMESTAMP'2001-01-01 10:20:33','2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def');
SELECT DECODE(NULL,TIMESTAMP'2001-01-01 10:20:31','then1',NULL,'then2NULL','2001-01-01 10:20:33','then3','def');
SELECT DECODE('w1','w1','then1','w2','then2','def');
SELECT DECODE('w2','w1','then1','w2','then2','def');
SELECT DECODE('w3','w1','then1',NULL,'then2NULL','w3','then3','def');
SELECT DECODE(NULL,'w1','then1',NULL,'then2NULL','w3','then3','def');
SELECT DECODE(1,1,'then1',2,'then2','def');
SELECT DECODE(2,1,'then1',2,'then2','def');
SELECT DECODE(3,1,'then1',NULL,'then2NULL',3,'then3','def');
SELECT DECODE(NULL,1,'then1',NULL,'then2NULL',3,'then3','def');
SELECT DECODE(CAST(NULL AS SIGNED),1,'then1',NULL,'then2NULL',3,'then3','def');
SELECT DECODE(1.0,1.0,'then1',2.0,'then2','def');
SELECT DECODE(2.0,1.0,'then1',2.0,'then2','def');
SELECT DECODE(3.0,1.0,'then1',NULL,'then2NULL',3.0,'then3','def');
SELECT DECODE(NULL,1.0,'then1',NULL,'then2NULL',3.0,'then3','def');
SELECT DECODE(CAST(NULL AS DECIMAL),1.0,'then1',NULL,'then2NULL',3.0,'then3','def');
SELECT DECODE(1e0,1e0,'then1',2e0,'then2','def');
SELECT DECODE(2e0,1e0,'then1',2e0,'then2','def');
SELECT DECODE(3e0,1e0,'then1',NULL,'then2NULL',3e0,'then3','def');
SELECT DECODE(NULL,1e0,'then1',NULL,'then2NULL',3e0,'then3','def');
SELECT DECODE(CAST(NULL AS DOUBLE),1e0,'then1',NULL,'then2NULL',3e0,'then3','def');
SELECT DECODE(NULL,NULL,1,2) FROM DUAL;
SELECT DECODE(NULL,10,10,NULL,1,2) FROM DUAL;
SELECT DECODE_ORACLE(NULL,NULL,1,2) FROM DUAL;
SELECT DECODE_ORACLE(NULL,10,10,NULL,1,2) FROM DUAL;

View File

@ -0,0 +1,33 @@
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
#
# MDEV-13003 - Oracle compatibility : Replace function
#
SELECT REPLACE(null,'a','b') ;
REPLACE(null,'a','b')
NULL
SELECT REPLACE('ab',null,'b') ;
REPLACE('ab',null,'b')
ab
SELECT REPLACE('ab','a',null) ;
REPLACE('ab','a',null)
b
SELECT REPLACE('ab',null,null) ;
REPLACE('ab',null,null)
ab
SELECT REPLACE('aaa','a',null) ;
REPLACE('aaa','a',null)
NULL
EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ;
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 replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)"
CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)" latin1 latin1_swedish_ci
SELECT * FROM v1;
REPLACE('ab','a',null)
b
DROP VIEW v1;

View File

@ -0,0 +1,22 @@
#
# Testing replace with null args
#
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
--echo #
--echo # MDEV-13003 - Oracle compatibility : Replace function
--echo #
SELECT REPLACE(null,'a','b') ;
SELECT REPLACE('ab',null,'b') ;
SELECT REPLACE('ab','a',null) ;
SELECT REPLACE('ab',null,null) ;
SELECT REPLACE('aaa','a',null) ;
EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ;
CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;

View File

@ -0,0 +1,171 @@
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
#
# MDEV-15664 sql_mode=ORACLE: Make TRIM return NULL instead of empty string
#
SELECT TRIM('abc'), TRIM('abc ')||'.', '.'||TRIM(' abc ')||'.', TRIM(' '), TRIM(NULL), TRIM(SPACE(0)),TRIM(SPACE(10)) FROM dual;
TRIM('abc') TRIM('abc ')||'.' '.'||TRIM(' abc ')||'.' TRIM(' ') TRIM(NULL) TRIM(SPACE(0)) TRIM(SPACE(10))
abc abc. .abc. NULL NULL NULL NULL
SELECT TRIM(TRAILING 'abc' FROM 'abc');
TRIM(TRAILING 'abc' FROM 'abc')
NULL
SELECT TRIM(TRAILING 'abc' FROM 'abc ');
TRIM(TRAILING 'abc' FROM 'abc ')
abc
SELECT TRIM(TRAILING 'abc' FROM ' abc');
TRIM(TRAILING 'abc' FROM ' abc')
SELECT TRIM(LEADING 'abc' FROM 'abc');
TRIM(LEADING 'abc' FROM 'abc')
NULL
SELECT TRIM(LEADING 'abc' FROM 'abc ');
TRIM(LEADING 'abc' FROM 'abc ')
SELECT TRIM(LEADING 'abc' FROM ' abc');
TRIM(LEADING 'abc' FROM ' abc')
abc
SELECT TRIM(BOTH 'abc' FROM 'abc');
TRIM(BOTH 'abc' FROM 'abc')
NULL
SELECT TRIM(BOTH 'abc' FROM 'abc ');
TRIM(BOTH 'abc' FROM 'abc ')
SELECT TRIM(BOTH 'abc' FROM ' abc');
TRIM(BOTH 'abc' FROM ' abc')
SELECT RTRIM('abc'), RTRIM('abc ')||'.', RTRIM(' abc ')||'.', RTRIM(' '), RTRIM(NULL), RTRIM(SPACE(0)),RTRIM(SPACE(10)) FROM dual;
RTRIM('abc') RTRIM('abc ')||'.' RTRIM(' abc ')||'.' RTRIM(' ') RTRIM(NULL) RTRIM(SPACE(0)) RTRIM(SPACE(10))
abc abc. abc. NULL NULL NULL NULL
SELECT LTRIM('abc'), LTRIM('abc '), LTRIM(' abc '), LTRIM(' '), LTRIM(NULL), LTRIM(SPACE(0)),LTRIM(SPACE(10)) FROM dual;
LTRIM('abc') LTRIM('abc ') LTRIM(' abc ') LTRIM(' ') LTRIM(NULL) LTRIM(SPACE(0)) LTRIM(SPACE(10))
abc abc abc NULL NULL NULL NULL
CREATE TABLE t1 (c1 VARCHAR(10),ord INTEGER);
INSERT INTO t1 VALUES ('abc',1);
INSERT INTO t1 VALUES (SPACE(0),2);
INSERT INTO t1 VALUES ('',3);
INSERT INTO t1 VALUES (' ',4);
INSERT INTO t1 VALUES (' ',5);
INSERT INTO t1 VALUES (' a ',6);
INSERT INTO t1 VALUES ('aa',7);
INSERT INTO t1 VALUES ('aabb',8);
INSERT INTO t1 VALUES ('bbaa',9);
INSERT INTO t1 VALUES ('aabbaa',10);
SELECT ord,'['||c1||']','.'||COALESCE(TRIM(LEADING 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord;
ord '['||c1||']' '.'||COALESCE(TRIM(LEADING 'a' FROM c1),'NULL')||'.'
1 [abc] .bc.
2 [] .NULL.
3 [] .NULL.
4 [ ] . .
5 [ ] . .
6 [ a ] . a .
7 [aa] .NULL.
8 [aabb] .bb.
9 [bbaa] .bbaa.
10 [aabbaa] .bbaa.
SELECT ord,'['||c1||']','.'||COALESCE(TRIM(TRAILING 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord;
ord '['||c1||']' '.'||COALESCE(TRIM(TRAILING 'a' FROM c1),'NULL')||'.'
1 [abc] .abc.
2 [] .NULL.
3 [] .NULL.
4 [ ] . .
5 [ ] . .
6 [ a ] . a .
7 [aa] .NULL.
8 [aabb] .aabb.
9 [bbaa] .bb.
10 [aabbaa] .aabb.
SELECT ord,'['||c1||']','.'||COALESCE(TRIM(BOTH 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord;
ord '['||c1||']' '.'||COALESCE(TRIM(BOTH 'a' FROM c1),'NULL')||'.'
1 [abc] .bc.
2 [] .NULL.
3 [] .NULL.
4 [ ] . .
5 [ ] . .
6 [ a ] . a .
7 [aa] .NULL.
8 [aabb] .bb.
9 [bbaa] .bb.
10 [aabbaa] .bb.
SELECT ord,'['||c1||']',COALESCE(LTRIM(c1),'NULL') FROM t1 ORDER BY ord;
ord '['||c1||']' COALESCE(LTRIM(c1),'NULL')
1 [abc] abc
2 [] NULL
3 [] NULL
4 [ ] NULL
5 [ ] NULL
6 [ a ] a
7 [aa] aa
8 [aabb] aabb
9 [bbaa] bbaa
10 [aabbaa] aabbaa
SELECT ord,'['||c1||']',COALESCE(RTRIM(c1),'NULL')||'.' FROM t1 ORDER BY ord;
ord '['||c1||']' COALESCE(RTRIM(c1),'NULL')||'.'
1 [abc] abc.
2 [] NULL.
3 [] NULL.
4 [ ] NULL.
5 [ ] NULL.
6 [ a ] a.
7 [aa] aa.
8 [aabb] aabb.
9 [bbaa] bbaa.
10 [aabbaa] aabbaa.
EXPLAIN EXTENDED SELECT TRIM('abc'),
TRIM(BOTH 'a' FROM 'abc'),
TRIM(LEADING 'a' FROM 'abc'),
TRIM(TRAILING 'a' FROM 'abc') ;
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 trim_oracle('abc') AS "TRIM('abc')",trim_oracle(both 'a' from 'abc') AS "TRIM(BOTH 'a' FROM 'abc')",trim_oracle(leading 'a' from 'abc') AS "TRIM(LEADING 'a' FROM 'abc')",trim_oracle(trailing 'a' from 'abc') AS "TRIM(TRAILING 'a' FROM 'abc')"
EXPLAIN EXTENDED SELECT RTRIM('abc'),
LTRIM('abc');
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 rtrim_oracle('abc') AS "RTRIM('abc')",ltrim_oracle('abc') AS "LTRIM('abc')"
CREATE VIEW v1 AS SELECT ord,TRIM('abc'),RTRIM('abc'),LTRIM('abc'),
'['||c1||']',
TRIM(LEADING 'a' FROM c1),
TRIM(TRAILING 'a' FROM c1),
TRIM(BOTH 'a' FROM c1),
LTRIM(c1),
RTRIM(c1)
FROM t1 ORDER BY ord ;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
v1 CREATE VIEW "v1" AS select "t1"."ord" AS "ord",trim_oracle('abc') AS "TRIM('abc')",rtrim_oracle('abc') AS "RTRIM('abc')",ltrim_oracle('abc') AS "LTRIM('abc')",concat_operator_oracle(concat_operator_oracle('[',"t1"."c1"),']') AS "'['||c1||']'",trim_oracle(leading 'a' from "t1"."c1") AS "TRIM(LEADING 'a' FROM c1)",trim_oracle(trailing 'a' from "t1"."c1") AS "TRIM(TRAILING 'a' FROM c1)",trim_oracle(both 'a' from "t1"."c1") AS "TRIM(BOTH 'a' FROM c1)",ltrim_oracle("t1"."c1") AS "LTRIM(c1)",rtrim_oracle("t1"."c1") AS "RTRIM(c1)" from "t1" order by "t1"."ord" latin1 latin1_swedish_ci
SELECT * FROM v1;
ord TRIM('abc') RTRIM('abc') LTRIM('abc') '['||c1||']' TRIM(LEADING 'a' FROM c1) TRIM(TRAILING 'a' FROM c1) TRIM(BOTH 'a' FROM c1) LTRIM(c1) RTRIM(c1)
1 abc abc abc [abc] bc abc bc abc abc
2 abc abc abc [] NULL NULL NULL NULL NULL
3 abc abc abc [] NULL NULL NULL NULL NULL
4 abc abc abc [ ] NULL NULL
5 abc abc abc [ ] NULL NULL
6 abc abc abc [ a ] a a a a a
7 abc abc abc [aa] NULL NULL NULL aa aa
8 abc abc abc [aabb] bb aabb bb aabb aabb
9 abc abc abc [bbaa] bbaa bb bb bbaa bbaa
10 abc abc abc [aabbaa] bbaa aabb bb aabbaa aabbaa
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (c1 VARCHAR(10) NOT NULL);
CREATE TABLE t2 AS SELECT TRIM(LEADING 'a' FROM c1) AS C1,
TRIM(TRAILING 'a' FROM c1) AS C2,
TRIM(BOTH 'a' FROM c1) AS C3,
LTRIM(c1) AS C4,
RTRIM(c1) AS C5
FROM t1;
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE "t2" (
"C1" varchar(10) DEFAULT NULL,
"C2" varchar(10) DEFAULT NULL,
"C3" varchar(10) DEFAULT NULL,
"C4" varchar(10) DEFAULT NULL,
"C5" varchar(10) DEFAULT NULL
)
DROP TABLE t2;
DROP TABLE t1;
CREATE TABLE trim_oracle (trim_oracle int);
DROP TABLE trim_oracle;

View File

@ -0,0 +1,78 @@
SET sql_mode=ORACLE;
SET default_storage_engine=ColumnStore;
--echo #
--echo # MDEV-15664 sql_mode=ORACLE: Make TRIM return NULL instead of empty string
--echo #
SELECT TRIM('abc'), TRIM('abc ')||'.', '.'||TRIM(' abc ')||'.', TRIM(' '), TRIM(NULL), TRIM(SPACE(0)),TRIM(SPACE(10)) FROM dual;
SELECT TRIM(TRAILING 'abc' FROM 'abc');
SELECT TRIM(TRAILING 'abc' FROM 'abc ');
SELECT TRIM(TRAILING 'abc' FROM ' abc');
SELECT TRIM(LEADING 'abc' FROM 'abc');
SELECT TRIM(LEADING 'abc' FROM 'abc ');
SELECT TRIM(LEADING 'abc' FROM ' abc');
SELECT TRIM(BOTH 'abc' FROM 'abc');
SELECT TRIM(BOTH 'abc' FROM 'abc ');
SELECT TRIM(BOTH 'abc' FROM ' abc');
SELECT RTRIM('abc'), RTRIM('abc ')||'.', RTRIM(' abc ')||'.', RTRIM(' '), RTRIM(NULL), RTRIM(SPACE(0)),RTRIM(SPACE(10)) FROM dual;
SELECT LTRIM('abc'), LTRIM('abc '), LTRIM(' abc '), LTRIM(' '), LTRIM(NULL), LTRIM(SPACE(0)),LTRIM(SPACE(10)) FROM dual;
CREATE TABLE t1 (c1 VARCHAR(10),ord INTEGER);
INSERT INTO t1 VALUES ('abc',1);
INSERT INTO t1 VALUES (SPACE(0),2);
INSERT INTO t1 VALUES ('',3);
INSERT INTO t1 VALUES (' ',4);
INSERT INTO t1 VALUES (' ',5);
INSERT INTO t1 VALUES (' a ',6);
INSERT INTO t1 VALUES ('aa',7);
INSERT INTO t1 VALUES ('aabb',8);
INSERT INTO t1 VALUES ('bbaa',9);
INSERT INTO t1 VALUES ('aabbaa',10);
SELECT ord,'['||c1||']','.'||COALESCE(TRIM(LEADING 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord;
SELECT ord,'['||c1||']','.'||COALESCE(TRIM(TRAILING 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord;
SELECT ord,'['||c1||']','.'||COALESCE(TRIM(BOTH 'a' FROM c1),'NULL')||'.' FROM t1 ORDER BY ord;
SELECT ord,'['||c1||']',COALESCE(LTRIM(c1),'NULL') FROM t1 ORDER BY ord;
SELECT ord,'['||c1||']',COALESCE(RTRIM(c1),'NULL')||'.' FROM t1 ORDER BY ord;
EXPLAIN EXTENDED SELECT TRIM('abc'),
TRIM(BOTH 'a' FROM 'abc'),
TRIM(LEADING 'a' FROM 'abc'),
TRIM(TRAILING 'a' FROM 'abc') ;
EXPLAIN EXTENDED SELECT RTRIM('abc'),
LTRIM('abc');
CREATE VIEW v1 AS SELECT ord,TRIM('abc'),RTRIM('abc'),LTRIM('abc'),
'['||c1||']',
TRIM(LEADING 'a' FROM c1),
TRIM(TRAILING 'a' FROM c1),
TRIM(BOTH 'a' FROM c1),
LTRIM(c1),
RTRIM(c1)
FROM t1 ORDER BY ord ;
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (c1 VARCHAR(10) NOT NULL);
CREATE TABLE t2 AS SELECT TRIM(LEADING 'a' FROM c1) AS C1,
TRIM(TRAILING 'a' FROM c1) AS C2,
TRIM(BOTH 'a' FROM c1) AS C3,
LTRIM(c1) AS C4,
RTRIM(c1) AS C5
FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
CREATE TABLE trim_oracle (trim_oracle int);
DROP TABLE trim_oracle;

View File

@ -3,6 +3,7 @@ include_directories( ${ENGINE_COMMON_INCLUDES} )
########### next target ############### ########### next target ###############
# func_decode_oracle.cpp
set(funcexp_LIB_SRCS set(funcexp_LIB_SRCS
functor.cpp functor.cpp
@ -20,6 +21,7 @@ set(funcexp_LIB_SRCS
func_char_length.cpp func_char_length.cpp
func_coalesce.cpp func_coalesce.cpp
func_concat.cpp func_concat.cpp
func_concat_oracle.cpp
func_concat_ws.cpp func_concat_ws.cpp
func_conv.cpp func_conv.cpp
func_crc32.cpp func_crc32.cpp
@ -31,6 +33,7 @@ set(funcexp_LIB_SRCS
func_dayofweek.cpp func_dayofweek.cpp
func_dayofyear.cpp func_dayofyear.cpp
func_decode.cpp func_decode.cpp
func_decode_oracle.cpp
func_div.cpp func_div.cpp
func_elt.cpp func_elt.cpp
func_encode.cpp func_encode.cpp
@ -60,6 +63,7 @@ set(funcexp_LIB_SRCS
func_length.cpp func_length.cpp
func_lpad.cpp func_lpad.cpp
func_ltrim.cpp func_ltrim.cpp
func_ltrim_oracle.cpp
func_makedate.cpp func_makedate.cpp
func_maketime.cpp func_maketime.cpp
func_math.cpp func_math.cpp
@ -79,11 +83,13 @@ set(funcexp_LIB_SRCS
func_regexp.cpp func_regexp.cpp
func_repeat.cpp func_repeat.cpp
func_replace.cpp func_replace.cpp
func_replace_oracle.cpp
func_reverse.cpp func_reverse.cpp
func_right.cpp func_right.cpp
func_round.cpp func_round.cpp
func_rpad.cpp func_rpad.cpp
func_rtrim.cpp func_rtrim.cpp
func_rtrim_oracle.cpp
func_second.cpp func_second.cpp
func_sec_to_time.cpp func_sec_to_time.cpp
func_sha.cpp func_sha.cpp
@ -101,6 +107,7 @@ set(funcexp_LIB_SRCS
func_timestampdiff.cpp func_timestampdiff.cpp
func_to_days.cpp func_to_days.cpp
func_trim.cpp func_trim.cpp
func_trim_oracle.cpp
func_truncate.cpp func_truncate.cpp
func_ucase.cpp func_ucase.cpp
func_unhex.cpp func_unhex.cpp

View File

@ -0,0 +1,78 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <string>
using namespace std;
#include "functor_str.h"
#include "functioncolumn.h"
#include "utils_utf8.h"
using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "dataconvert.h"
using namespace dataconvert;
namespace funcexp
{
CalpontSystemCatalog::ColType Func_concat_oracle::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType )
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
// Returns the string that results from concatenating the arguments.
// concat_oracle() returns NULL all arguments are NULL.
// single arguments null is replaced by "".
//
string Func_concat_oracle::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType&)
{
string ret;
string tmp;
stringValue(parm[0], row, isNull, ret);
// Oracle Mode should replace NULL with "" unless all values are NULL
if (isNull)
{
ret = "";
isNull = false;
}
// TODO: do a better job of cutting down the number re-allocations.
// look at Item_func_concat::realloc_result for ideas and use
// std::string:resize() appropriatly.
for ( unsigned int id = 1 ; id < parm.size() ; id++)
{
stringValue(parm[id], row, isNull, tmp);
if (isNull)
{
tmp = "";
isNull = false;
}
ret.append(tmp);
}
return ret;
}
} // namespace funcexp
// vim:ts=4 sw=4:

View File

@ -1,3 +1,20 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
using namespace std; using namespace std;

View File

@ -0,0 +1,585 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <string>
//#define NDEBUG
#include <cassert>
using namespace std;
#include "functor_all.h"
#include "functioncolumn.h"
#include "predicateoperator.h"
using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "errorcodes.h"
#include "idberrorinfo.h"
#include "errorids.h"
using namespace logging;
#include "utils_utf8.h"
using namespace funcexp;
#include "collation.h"
namespace
{
using namespace funcexp;
inline uint64_t simple_case_cmp(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = 0; // index to the parm list
uint64_t n = 0; // remove expression from count of expression_i + result_i
uint64_t hasElse = (parm.size() - 1) % 2; // if 1, then ELSE exist
uint64_t whereCount = hasElse ? (parm.size() - 2) / 2 : (parm.size() - 1) / 2;
bool foundIt = false;
switch (operationColType.colDataType)
{
case execplan::CalpontSystemCatalog::TINYINT:
case execplan::CalpontSystemCatalog::SMALLINT:
case execplan::CalpontSystemCatalog::MEDINT:
case execplan::CalpontSystemCatalog::INT:
case execplan::CalpontSystemCatalog::BIGINT:
case execplan::CalpontSystemCatalog::DATE:
{
int64_t ev = parm[n]->data()->getIntVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getIntVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::DATETIME:
{
int64_t ev = parm[n]->data()->getDatetimeIntVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getDatetimeIntVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::TIMESTAMP:
{
int64_t ev = parm[n]->data()->getTimestampIntVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getTimestampIntVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::TIME:
{
int64_t ev = parm[n]->data()->getTimeIntVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getTimeIntVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::UBIGINT:
case execplan::CalpontSystemCatalog::UINT:
case execplan::CalpontSystemCatalog::UMEDINT:
case execplan::CalpontSystemCatalog::UTINYINT:
case execplan::CalpontSystemCatalog::USMALLINT:
{
uint64_t ev = parm[n]->data()->getUintVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getUintVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::CHAR:
case execplan::CalpontSystemCatalog::TEXT:
case execplan::CalpontSystemCatalog::VARCHAR:
{
const string& ev = parm[n]->data()->getStrVal(row, isNull);
if (isNull)
break;
CHARSET_INFO* cs = parm[n]->data()->resultType().getCharset();
for (i = 1; i <= whereCount; i++)
{
//BUG 5362
const string& p1 = parm[i]->data()->getStrVal(row, isNull);
if (isNull)
break;
if (cs->strnncoll(ev.c_str(), ev.length(), p1.c_str(), p1.length()) == 0)
{
foundIt = true;
break;
}
}
break;
}
case execplan::CalpontSystemCatalog::DECIMAL:
case execplan::CalpontSystemCatalog::UDECIMAL:
{
IDB_Decimal ev = parm[n]->data()->getDecimalVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getDecimalVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::DOUBLE:
case execplan::CalpontSystemCatalog::UDOUBLE:
{
double ev = parm[n]->data()->getDoubleVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getDoubleVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::FLOAT:
case execplan::CalpontSystemCatalog::UFLOAT:
{
float ev = parm[n]->data()->getFloatVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getFloatVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
case execplan::CalpontSystemCatalog::LONGDOUBLE:
{
long double ev = parm[n]->data()->getLongDoubleVal(row, isNull);
if (isNull)
break;
for (i = 1; i <= whereCount; i++)
{
if (ev == parm[i]->data()->getLongDoubleVal(row, isNull) && !isNull)
{
foundIt = true;
break;
}
else
isNull = false;
}
break;
}
default:
{
std::ostringstream oss;
oss << "case: datatype of " << execplan::colDataTypeToString(operationColType.colDataType);
throw logging::IDBExcept(oss.str(), ERR_DATATYPE_NOT_SUPPORT);
}
}
if (!foundIt && !hasElse)
isNull = true;
else if (!foundIt && hasElse && !isNull)
{
i = parm.size() - 1;
}
else if (isNull && hasElse)
// BUG 5110. Only way we can exit above with isNull == true is when ev is NULL
// if so and we have else condition we need to use it by setting i = else
{
i = parm.size() - 1;
isNull = false;
}
if (foundIt)
{
i += whereCount;
}
return i;
}
CalpontSystemCatalog::ColType caseOperationType(FunctionParm& fp,
CalpontSystemCatalog::ColType& resultType,
bool simpleCase)
{
uint64_t simple = simpleCase ? 1 : 0;
bool hasElse = (((fp.size()-simple) % 2) != 0); // if 1, then ELSE exist
uint64_t parmCount = hasElse ? (fp.size() - 2) : (fp.size() - 1);
uint64_t whereCount = hasElse ? (fp.size() - 2 + simple) / 2 : (fp.size() - 1) / 2 + simple;
bool allStringO = true;
bool allStringR = true;
FunctionParm::size_type l = fp.size() - 1; // last fp index
idbassert(fp[l]->data());
CalpontSystemCatalog::ColType oct = fp[l]->data()->resultType();
CalpontSystemCatalog::ColType rct = resultType;
bool operation = true;
for (uint64_t i = 0; i <= parmCount; i++)
{
// for SimpleCase, we return the type of the case expression,
// which will always be in position 0.
if (i == 0 && simpleCase)
{
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
PredicateOperator op;
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
i += 1;
}
// operation or result type
operation = ((i > 0+simple) && (i <= whereCount));
if (fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::CHAR &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::TEXT &&
fp[i]->data()->resultType().colDataType != CalpontSystemCatalog::VARCHAR)
{
// this is not a string column
PredicateOperator op;
if (operation)
{
if (!simpleCase)
{
op.setOpType(oct, fp[i]->data()->resultType());
allStringO = false;
oct = op.operationType();
}
}
// If any parm is of string type, the result type should be string. (same as if)
else if (rct.colDataType != CalpontSystemCatalog::CHAR &&
rct.colDataType != CalpontSystemCatalog::TEXT &&
rct.colDataType != CalpontSystemCatalog::VARCHAR)
{
op.setOpType(rct, fp[i]->data()->resultType());
allStringR = false;
rct = op.operationType();
}
}
else
{
// this is a string
// If any parm is of string type, the result type should be string. (same as if)
allStringR = true;
}
}
if (allStringO)
{
oct.colDataType = CalpontSystemCatalog::VARCHAR;
oct.colWidth = 255;
}
if (allStringR)
{
rct.colDataType = CalpontSystemCatalog::VARCHAR;
rct.colWidth = 255;
}
if (rct.scale != 0 && rct.colDataType == CalpontSystemCatalog::BIGINT)
rct.colDataType = CalpontSystemCatalog::DECIMAL;
if (oct.scale != 0 && oct.colDataType == CalpontSystemCatalog::BIGINT)
oct.colDataType = CalpontSystemCatalog::DECIMAL;
resultType = rct;
return oct;
}
}
namespace funcexp
{
// simple CASE:
// SELECT CASE ("expression")
// WHEN "condition1" THEN "result1"
// WHEN "condition2" THEN "result2"
// ...
// [ELSE "resultN"]
// END
//
// simple CASE parm order:
// expression condition1 condition2 ... result1 result2 ... [resultN]
//
// Note that this order changed in 10.2.14, see MCOL-1341
CalpontSystemCatalog::ColType Func_decode_oracle::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
return caseOperationType(fp, resultType, true);
}
bool Func_decode_oracle::getBoolVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return false;
ParseTree* lop = parm[i]->left();
ParseTree* rop = parm[i]->right();
if (lop && rop)
{
return (reinterpret_cast<Operator*>(parm[i]->data()))->getBoolVal(row, isNull, lop, rop);
}
return parm[i]->data()->getBoolVal(row, isNull);
}
int64_t Func_decode_oracle::getIntVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return joblist::BIGINTNULL;
return parm[i]->data()->getIntVal(row, isNull);
}
string Func_decode_oracle::getStrVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return string("");
return parm[i]->data()->getStrVal(row, isNull);
}
IDB_Decimal Func_decode_oracle::getDecimalVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return IDB_Decimal(); // need a null value for IDB_Decimal??
return parm[i]->data()->getDecimalVal(row, isNull);
}
double Func_decode_oracle::getDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return doubleNullVal();
return parm[i]->data()->getDoubleVal(row, isNull);
}
long double Func_decode_oracle::getLongDoubleVal(Row& row,
FunctionParm& parm,
bool& isNull,
CalpontSystemCatalog::ColType& operationColType)
{
uint64_t i = simple_case_cmp(row, parm, isNull, operationColType);
if (isNull)
return doubleNullVal();
return parm[i]->data()->getLongDoubleVal(row, isNull);
}
int32_t Func_decode_oracle::getDateIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATENULL;
return parm[i]->data()->getDateIntVal(row, isNull);
}
int64_t Func_decode_oracle::getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::DATETIMENULL;
return parm[i]->data()->getDatetimeIntVal(row, isNull);
}
int64_t Func_decode_oracle::getTimestampIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::TIMESTAMPNULL;
return parm[i]->data()->getTimestampIntVal(row, isNull);
}
int64_t Func_decode_oracle::getTimeIntVal(rowgroup::Row& row,
FunctionParm& parm,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct)
{
uint64_t i = simple_case_cmp(row, parm, isNull, op_ct);
if (isNull)
return joblist::TIMENULL;
return parm[i]->data()->getTimeIntVal(row, isNull);
}
}

View File

@ -1,3 +1,21 @@
/* Copyright (C) 2014 InfiniDB, Inc.
Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <cstdlib> #include <cstdlib>
#include <string> #include <string>
using namespace std; using namespace std;

View File

@ -0,0 +1,107 @@
/* Copyright (C) 2014 InfiniDB, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/****************************************************************************
* $Id: func_ltrim.cpp 3923 2013-06-19 21:43:06Z bwilkinson $
*
*
****************************************************************************/
#include <string>
using namespace std;
#include "functor_str.h"
#include "functioncolumn.h"
#include "utils_utf8.h"
using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "joblisttypes.h"
using namespace joblist;
#include "collation.h"
namespace funcexp
{
CalpontSystemCatalog::ColType Func_ltrim_oracle::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_ltrim_oracle::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT+binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
if (binTLen == 1)
{
// If the trim string is 1 byte, don't waste cpu for memcmp
while (pos < end && *pos == *posT)
{
++pos;
--binLen;
}
}
else
{
while (pos+binTLen <= end && memcmp(pos,posT,binTLen) == 0)
{
pos += binTLen;
binLen -= binTLen;
}
}
// Turn back to a string
std::string ret(pos, binLen);
if (binLen == 0)
{
isNull = true;
}
return ret;
}
} // namespace funcexp
// vim:ts=4 sw=4:

View File

@ -0,0 +1,178 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <string>
using namespace std;
#include "functor_str.h"
#include "functioncolumn.h"
using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "joblisttypes.h"
using namespace joblist;
#include "collation.h"
namespace funcexp
{
CalpontSystemCatalog::ColType Func_replace_oracle::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_replace_oracle::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& ct)
{
CHARSET_INFO* cs = ct.getCharset();
const string& str = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
size_t strLen = str.length();
const string& fromstr = fp[1]->data()->getStrVal(row, isNull);
if (isNull)
return "";
if (fromstr.length() == 0)
return str;
size_t fromLen = fromstr.length();
const string& tostr = fp[2]->data()->getStrVal(row, isNull);
if (isNull)
return "";
size_t toLen = tostr.length();
bool binaryCmp = (cs->state & MY_CS_BINSORT) || !cs->use_mb();
string newstr;
size_t pos = 0;
if (binaryCmp)
{
// Count the number of fromstr in strend so we can reserve buffer space.
int count = 0;
do
{
++count;
pos = str.find(fromstr, pos + fromLen);
}
while (pos != string::npos);
newstr.reserve(strLen + (count * ((int)toLen - (int)fromLen)) + 1);
uint32_t i = 0;
pos = str.find(fromstr);
if (pos == string::npos)
return str;
// Move the stuff into newstr
do
{
if (pos > i)
newstr = newstr + str.substr(i, pos - i);
newstr = newstr + tostr;
i = pos + fromLen;
pos = str.find(fromstr, i);
}
while (pos != string::npos);
newstr = newstr + str.substr(i, string::npos);
}
else
{
// UTF
const char* src = str.c_str();
const char* srcEnd = src + strLen;
const char* srchEnd = srcEnd - fromLen + 1;
const char* from = fromstr.c_str();
const char* fromEnd = from + fromLen;
const char* to = tostr.c_str();
const char* ptr = src;
char *i,*j;
size_t count = 10; // Some arbitray number to reserve some space to start.
int growlen = (int)toLen - (int)fromLen;
growlen = growlen < 1 ? 1 : growlen;
growlen *= count;
newstr.reserve(strLen + (count * growlen) + 1);
size_t maxsize = newstr.capacity();
uint32_t l;
// We don't know where byte patterns might match so
// we start at the beginning of the string and move forward
// one character at a time until we find a match. Then we can
// move the src bytes and add in the to bytes,then try again.
while (ptr < srchEnd)
{
bool found = false;
if (*ptr == *from) // If the first byte matches, maybe we have a match
{
// Do a byte by byte compare of src at that spot against from
i = const_cast<char*>(ptr) + 1;
j = const_cast<char*>(from) + 1;
found = true;
while (j != fromEnd)
{
if (*i++ != *j++)
{
found = false;
break;
}
}
}
if (found)
{
if (ptr < i)
{
int mvsize = ptr - src;
if (newstr.length() + mvsize + toLen > maxsize)
{
// We need a re-alloc
newstr.reserve(maxsize + growlen);
maxsize = newstr.capacity();
growlen *= 2;
}
newstr.append(src, ptr - src);
src += mvsize + fromLen;
ptr = src;
}
newstr.append(to, toLen);
}
else
{
// move to the next character
if ((l = my_ismbchar(cs, ptr, srcEnd))) // returns the number of bytes in the leading char or zero if one byte
ptr += l;
else
++ptr;
}
}
// Copy in the trailing src chars.
newstr.append(src, srcEnd - src);
}
return newstr;
}
} // namespace funcexp
// vim:ts=4 sw=4:

View File

@ -0,0 +1,169 @@
/* Copyright (C) 2014 InfiniDB, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/****************************************************************************
* $Id: func_rtrim.cpp 3923 2013-06-19 21:43:06Z bwilkinson $
*
*
****************************************************************************/
#include <string>
using namespace std;
#include "functor_str.h"
#include "functioncolumn.h"
#include "utils_utf8.h"
using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "joblisttypes.h"
using namespace joblist;
#include "collation.h"
namespace funcexp
{
CalpontSystemCatalog::ColType Func_rtrim_oracle::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_rtrim_oracle::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT+binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
if (binTLen == 1)
{
const char* ptr = pos;
if (cs->use_mb()) // This is a multi-byte charset
{
const char* p = pos;
uint32 l;
// Multibyte characters in the string give us alignment problems
// What we do here is skip past any multibyte characters. Whn
// don with this loop, ptr is pointing to a singlebyte char that
// is after all multibyte chars in the string, or to end.
while (ptr < end)
{
if ((l = my_ismbchar(cs, ptr, end))) // returns the number of bytes in the leading char or zero if one byte
{
ptr += l;
p = ptr;
}
else
{
++ptr;
}
}
ptr = p;
}
while (ptr < end && end[-1] == *posT)
{
--end;
--binLen;
}
}
else
{
// An uncommon case where the space character is > 1 byte
if (cs->use_mb()) // This is a multi-byte charset
{
// The problem is that the byte pattern at the end could
// match memcmp, but not be correct since the first byte compared
// may actually be a second or later byte from a previous char.
// We start at the beginning of the string and move forward
// one character at a time until we reach the end. Then we can
// safely compare and remove on character. Then back to the beginning
// and try again.
while (end - binTLen >= pos)
{
const char* p = pos;
uint32 l;
while (p + binTLen < end)
{
if ((l = my_ismbchar(cs, p, end))) // returns the number of bytes in the leading char or zero if one byte
p += l;
else
++p;
}
if (p + binTLen == end && memcmp(p,posT,binTLen) == 0)
{
end -= binTLen;
binLen -= binTLen;
}
else
{
break; // We've run out of places to look
}
}
}
else
{
// This implies we have a single byte charset and a multibyte
// space character.
// Should never get here, since rtrim only trims space characters
// Included for completeness.
while (end-binTLen >= pos && memcmp(end-binTLen,posT,binTLen) == 0)
{
end -= binTLen;
binLen -= binTLen;
}
}
}
// Turn back to a string
std::string ret(pos, binLen);
if (binLen == 0)
{
isNull = true;
}
return ret;
}
} // namespace funcexp
// vim:ts=4 sw=4:

View File

@ -0,0 +1,175 @@
/* Copyright (C) 2021 MariaDB Corporation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
#include <string>
using namespace std;
#include "functor_str.h"
#include "functioncolumn.h"
#include "utils_utf8.h"
using namespace execplan;
#include "rowgroup.h"
using namespace rowgroup;
#include "joblisttypes.h"
using namespace joblist;
#include "collation.h"
namespace funcexp
{
CalpontSystemCatalog::ColType Func_trim_oracle::operationType(FunctionParm& fp, CalpontSystemCatalog::ColType& resultType)
{
// operation type is not used by this functor
return fp[0]->data()->resultType();
}
std::string Func_trim_oracle::getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& type)
{
CHARSET_INFO* cs = type.getCharset();
// The original string
const string& src = fp[0]->data()->getStrVal(row, isNull);
if (isNull)
return "";
if (src.empty() || src.length() == 0)
return src;
// binLen represents the number of bytes in src
size_t binLen = src.length();
const char* pos = src.c_str();
const char* end = pos + binLen;
// strLen = the number of characters in src
size_t strLen = cs->numchars(pos, end);
// The trim characters.
const string& trim = (fp.size() > 1 ? fp[1]->data()->getStrVal(row, isNull) : " ");
// binTLen represents the number of bytes in trim
size_t binTLen = trim.length();
const char* posT = trim.c_str();
// strTLen = the number of characters in trim
size_t strTLen = cs->numchars(posT, posT+binTLen);
if (strTLen == 0 || strTLen > strLen)
return src;
if (binTLen == 1)
{
// If the trim string is 1 byte, don't waste cpu for memcmp
// Trim leading
while (pos < end && *pos == *posT)
{
++pos;
--binLen;
}
// Trim trailing
const char* ptr = pos;
if (cs->use_mb()) // This is a multi-byte charset
{
const char* p = pos;
uint32 l;
// Multibyte characters in the string give us alignment problems
// What we do here is skip past any multibyte characters. Whn
// don with this loop, ptr is pointing to a singlebyte char that
// is after all multibyte chars in the string, or to end.
while (ptr < end)
{
if ((l = my_ismbchar(cs, ptr, end))) // returns the number of bytes in the leading char or zero if one byte
{
ptr += l;
p = ptr;
}
else
{
++ptr;
}
}
ptr = p;
}
while (ptr < end && end[-1] == *posT)
{
--end;
--binLen;
}
}
else
{
// Trim leading is easy
while (pos+binTLen <= end && memcmp(pos,posT,binTLen) == 0)
{
pos += binTLen;
binLen -= binTLen;
}
// Trim trailing
if (cs->use_mb()) // This is a multi-byte charset
{
// The problem is that the byte pattern at the end could
// match memcmp, but not be correct since the first byte compared
// may actually be a second or later byte from a previous char.
// We start at the beginning of the string and move forward
// one character at a time until we reach the end. Then we can
// safely compare and remove one character. Then back to the beginning
// and try again.
while (end - binTLen >= pos)
{
const char* p = pos;
uint32_t l;
while (p + binTLen < end)
{
if ((l = my_ismbchar(cs, p, end))) // returns the number of bytes in the leading char or zero if one byte
p += l;
else
++p;
}
if (p + binTLen == end && memcmp(p,posT,binTLen) == 0)
{
end -= binTLen;
binLen -= binTLen;
}
else
{
break; // We've run out of places to look
}
}
}
else
{
while (end-binTLen >= pos && memcmp(end-binTLen,posT,binTLen) == 0)
{
end -= binTLen;
binLen -= binTLen;
}
}
}
// Turn back to a string
std::string ret(pos, binLen);
if (binLen == 0)
{
isNull = true;
}
return ret;
}
} // namespace funcexp
// vim:ts=4 sw=4:

View File

@ -97,6 +97,7 @@ FuncExp::FuncExp()
fFuncMap["char_length"] = new Func_char_length(); //dlh fFuncMap["char_length"] = new Func_char_length(); //dlh
fFuncMap["character_length"] = new Func_char_length(); //dlh fFuncMap["character_length"] = new Func_char_length(); //dlh
fFuncMap["coalesce"] = new Func_coalesce(); fFuncMap["coalesce"] = new Func_coalesce();
fFuncMap["concat_operator_oracle"] = new Func_concat_oracle();
fFuncMap["concat"] = new Func_concat(); fFuncMap["concat"] = new Func_concat();
fFuncMap["concat_ws"] = new Func_concat_ws(); fFuncMap["concat_ws"] = new Func_concat_ws();
fFuncMap["conv"] = new Func_conv(); fFuncMap["conv"] = new Func_conv();
@ -112,6 +113,7 @@ FuncExp::FuncExp()
fFuncMap["dayofweek"] = new Func_dayofweek(); //dlh fFuncMap["dayofweek"] = new Func_dayofweek(); //dlh
fFuncMap["dayofyear"] = new Func_dayofyear(); //dlh fFuncMap["dayofyear"] = new Func_dayofyear(); //dlh
fFuncMap["decode"] = new Func_decode(); // BT fFuncMap["decode"] = new Func_decode(); // BT
fFuncMap["decode_oracle"] = new Func_decode_oracle(); // BT
fFuncMap["degrees"] = new Func_degrees(); fFuncMap["degrees"] = new Func_degrees();
fFuncMap["DIV"] = new Func_div(); // MySQL use upper case for this function name fFuncMap["DIV"] = new Func_div(); // MySQL use upper case for this function name
fFuncMap["elt"] = new Func_elt(); fFuncMap["elt"] = new Func_elt();
@ -156,6 +158,7 @@ FuncExp::FuncExp()
fFuncMap["lower"] = new Func_lcase(); //dlh fFuncMap["lower"] = new Func_lcase(); //dlh
fFuncMap["lpad"] = new Func_lpad(); //dlh fFuncMap["lpad"] = new Func_lpad(); //dlh
fFuncMap["ltrim"] = new Func_ltrim(); //dlh fFuncMap["ltrim"] = new Func_ltrim(); //dlh
fFuncMap["ltrim_oracle"] = new Func_ltrim_oracle(); //dlh
fFuncMap["makedate"] = new Func_makedate(); fFuncMap["makedate"] = new Func_makedate();
fFuncMap["maketime"] = new Func_maketime(); fFuncMap["maketime"] = new Func_maketime();
fFuncMap["microsecond"] = new Func_microsecond(); fFuncMap["microsecond"] = new Func_microsecond();
@ -183,11 +186,13 @@ FuncExp::FuncExp()
fFuncMap["regexp"] = new Func_regexp(); //dlh fFuncMap["regexp"] = new Func_regexp(); //dlh
fFuncMap["repeat"] = new Func_repeat(); //dlh fFuncMap["repeat"] = new Func_repeat(); //dlh
fFuncMap["replace"] = new Func_replace(); //dlh fFuncMap["replace"] = new Func_replace(); //dlh
fFuncMap["replace_oracle"] = new Func_replace_oracle(); //dlh
fFuncMap["reverse"] = new Func_reverse(); //dlh fFuncMap["reverse"] = new Func_reverse(); //dlh
fFuncMap["right"] = new Func_right(); //dlh fFuncMap["right"] = new Func_right(); //dlh
fFuncMap["round"] = new Func_round(); fFuncMap["round"] = new Func_round();
fFuncMap["rpad"] = new Func_rpad(); //dlh fFuncMap["rpad"] = new Func_rpad(); //dlh
fFuncMap["rtrim"] = new Func_rtrim(); //dlh fFuncMap["rtrim"] = new Func_rtrim(); //dlh
fFuncMap["rtrim_oracle"] = new Func_rtrim_oracle(); //dlh
fFuncMap["second"] = new Func_second(); //dlh fFuncMap["second"] = new Func_second(); //dlh
fFuncMap["sec_to_time"] = new Func_sec_to_time(); fFuncMap["sec_to_time"] = new Func_sec_to_time();
fFuncMap["sha"] = new Func_sha(); fFuncMap["sha"] = new Func_sha();
@ -210,6 +215,7 @@ FuncExp::FuncExp()
fFuncMap["time_to_sec"] = new Func_time_to_sec(); //dlh fFuncMap["time_to_sec"] = new Func_time_to_sec(); //dlh
fFuncMap["to_days"] = new Func_to_days(); //dlh fFuncMap["to_days"] = new Func_to_days(); //dlh
fFuncMap["trim"] = new Func_trim(); //dlh fFuncMap["trim"] = new Func_trim(); //dlh
fFuncMap["trim_oracle"] = new Func_trim_oracle(); //dlh
fFuncMap["truncate"] = new Func_truncate(); //dlh fFuncMap["truncate"] = new Func_truncate(); //dlh
fFuncMap["ucase"] = new Func_ucase(); //dlh fFuncMap["ucase"] = new Func_ucase(); //dlh
fFuncMap["unhex"] = new Func_unhex(); fFuncMap["unhex"] = new Func_unhex();

View File

@ -122,6 +122,65 @@ public:
execplan::CalpontSystemCatalog::ColType& op_ct); execplan::CalpontSystemCatalog::ColType& op_ct);
}; };
class Func_decode_oracle : public Func_All
{
public:
Func_decode_oracle(): Func_All("decode_oracle") {}
virtual ~Func_decode_oracle() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
bool getBoolVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
int64_t getIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
double getDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
long double getLongDoubleVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
execplan::IDB_Decimal getDecimalVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
int32_t getDateIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
int64_t getDatetimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
int64_t getTimestampIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
int64_t getTimeIntVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_searched_case class /** @brief Func_searched_case class
*/ */

View File

@ -183,6 +183,22 @@ public:
}; };
/** @brief Func_concat_oracle class
*/
class Func_concat_oracle : public Func_Str
{
public:
Func_concat_oracle() : Func_Str("concat_operator_oracle") {}
virtual ~Func_concat_oracle() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_substr class /** @brief Func_substr class
*/ */
class Func_substr : public Func_Str class Func_substr : public Func_Str
@ -333,6 +349,55 @@ public:
execplan::CalpontSystemCatalog::ColType& op_ct); execplan::CalpontSystemCatalog::ColType& op_ct);
}; };
/** @brief Func_ltrim class
*/
class Func_ltrim_oracle : public Func_Str
{
public:
Func_ltrim_oracle() : Func_Str("ltrim_oracle") {}
virtual ~Func_ltrim_oracle() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_rtrim class
*/
class Func_rtrim_oracle : public Func_Str
{
public:
Func_rtrim_oracle() : Func_Str("rtrim_oracle") {}
virtual ~Func_rtrim_oracle() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_trim class
*/
class Func_trim_oracle : public Func_Str
{
public:
Func_trim_oracle() : Func_Str("trim_oracle") {}
virtual ~Func_trim_oracle() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_lpad class /** @brief Func_lpad class
*/ */
@ -386,6 +451,19 @@ public:
execplan::CalpontSystemCatalog::ColType& op_ct); execplan::CalpontSystemCatalog::ColType& op_ct);
}; };
class Func_replace_oracle : public Func_Str
{
public:
Func_replace_oracle() : Func_Str("replace_oracle") {}
virtual ~Func_replace_oracle() {}
execplan::CalpontSystemCatalog::ColType operationType(FunctionParm& fp, execplan::CalpontSystemCatalog::ColType& resultType);
std::string getStrVal(rowgroup::Row& row,
FunctionParm& fp,
bool& isNull,
execplan::CalpontSystemCatalog::ColType& op_ct);
};
/** @brief Func_right class /** @brief Func_right class
*/ */