diff --git a/mysql-test/suite/compat/oracle/r/empty-string.result b/mysql-test/suite/compat/oracle/r/empty-string.result
new file mode 100644
index 0000000..241622f
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/empty-string.result
@@ -0,0 +1,341 @@
+use test;
+#
+# MDEV-10574 sql_mode=ORACLE: IS NULL and empty strings
+#
+set session character_set_connection=latin2;
+set session character_set_client=cp1250;
+Test litteral
+SET sql_mode=ORACLE;
+select '',charset(''), null, charset(null), cast(null as varchar(10)), charset(cast(null as varchar(10))), 'x', charset('x');
+NULL	charset('')	NULL	charset(null)	cast(null as varchar(10))	charset(cast(null as varchar(10)))	x	charset('x')
+NULL	latin2	NULL	binary	NULL	latin2	x	latin2
+SET sql_mode=default;
+select '',charset(''), null, charset(null), cast(null as char(10)), charset(cast(null as char(10))), 'x', charset('x');
+	charset('')	NULL	charset(null)	cast(null as char(10))	charset(cast(null as char(10)))	x	charset('x')
+	latin2	NULL	binary	NULL	latin2	x	latin2
+Test NCHAR litteral
+SET sql_mode=ORACLE;
+select N'',charset(N''), N'x', charset(N'x');
+NULL	charset(N'')	x	charset(N'x')
+NULL	utf8	x	utf8
+SET sql_mode=default;
+select N'',charset(N''), N'x', charset(N'x');
+	charset(N'')	x	charset(N'x')
+	utf8	x	utf8
+Test charset prefix litteral
+SET sql_mode=ORACLE;
+select _cp1250 '',charset(_cp1250 ''), _cp1250 'x', charset(_cp1250 'x');
+NULL	charset(_cp1250 '')	x	charset(_cp1250 'x')
+NULL	cp1250	x	cp1250
+SET sql_mode=default;
+select _cp1250 '',charset(_cp1250 ''), _cp1250 'x', charset(_cp1250 'x');
+	charset(_cp1250 '')	x	charset(_cp1250 'x')
+	cp1250	x	cp1250
+SET sql_mode=ORACLE;
+Test of basic string function that must return null with '' in input
+select nvl(ascii(''),-1) from dual;
+nvl(ascii(''),-1)
+-1
+select nvl(cast('' as int),-1) from dual;
+nvl(cast('' as int),-1)
+-1
+select concat('','x'),nvl(concat('',''),'is null') from dual;
+concat('','x')	nvl(concat('',''),'is null')
+x	is null
+select nvl(instr('abc',''),-1) from dual;
+nvl(instr('abc',''),-1)
+-1
+select nvl(instr('',''),-1) from dual;
+nvl(instr('',''),-1)
+-1
+select nvl(instr('','b'),-1) from dual;
+nvl(instr('','b'),-1)
+-1
+select nvl(left('a',0),'is null') from dual;
+nvl(left('a',0),'is null')
+is null
+select nvl(length(''),-1) from dual;
+nvl(length(''),-1)
+-1
+select nvl(lpad('',10,' '),'is null'),
+nvl(lpad('',10,''),'is null'),
+nvl(lpad('x',10,''),'is null'),
+nvl(lpad('x',0,' '),'is null')
+from dual;
+nvl(lpad('',10,' '),'is null')	nvl(lpad('',10,''),'is null')	nvl(lpad('x',10,''),'is null')	nvl(lpad('x',0,' '),'is null')
+is null	is null	is null	is null
+select nvl(mid('abc',1,0),'is null') from dual;
+nvl(mid('abc',1,0),'is null')
+is null
+select nvl(mid('abc',10,1),'is null') from dual;
+nvl(mid('abc',10,1),'is null')
+is null
+select nvl(right('a',0),'is null') from dual;
+nvl(right('a',0),'is null')
+is null
+select nvl(rpad('',10,' '),'is null'),
+nvl(rpad('',10,''),'is null'),
+nvl(rpad('x',10,''),'is null'),
+nvl(rpad('x',0,' '),'is null')
+from dual;
+nvl(rpad('',10,' '),'is null')	nvl(rpad('',10,''),'is null')	nvl(rpad('x',10,''),'is null')	nvl(rpad('x',0,' '),'is null')
+is null	is null	is null	is null
+select nvl(replace('abc','a',''),'is null'),
+nvl(replace('abc','','x'),'is null'),
+nvl(replace('','a','b'),'is null'),
+nvl(replace('','','b'),'is null'),
+nvl(replace('','',''),'is null'),
+nvl(replace('aaa','a',null),'is null')
+from dual;
+nvl(replace('abc','a',''),'is null')	nvl(replace('abc','','x'),'is null')	nvl(replace('','a','b'),'is null')	nvl(replace('','','b'),'is null')	nvl(replace('','',''),'is null')	nvl(replace('aaa','a',null),'is null')
+bc	abc	is null	is null	is null	is null
+select nvl(substr('abc',1,0),'is null'),
+nvl(substr('abc',10,2),'is null'),
+nvl(substr('abc',0,2),'is null')
+from dual;
+nvl(substr('abc',1,0),'is null')	nvl(substr('abc',10,2),'is null')	nvl(substr('abc',0,2),'is null')
+is null	is null	ab
+Test substr with start at 0
+select nvl(substr('abc',0,0),'is null'),
+nvl(substr('abc',0,2),'is null'),
+nvl(substr('',0,2),'is null')
+from dual;
+nvl(substr('abc',0,0),'is null')	nvl(substr('abc',0,2),'is null')	nvl(substr('',0,2),'is null')
+is null	ab	is null
+select nvl(trim(''),'is null'),
+nvl(rtrim(''),'is null'),
+nvl(ltrim(''),'is null') from dual;
+nvl(trim(''),'is null')	nvl(rtrim(''),'is null')	nvl(ltrim(''),'is null')
+is null	is null	is null
+Test default on column
+create table t1 (c1 varchar(10) default '');
+show create table t1;
+Table	Create Table
+t1	CREATE TABLE "t1" (
+  "c1" varchar(10) DEFAULT NULL
+)
+drop table t1;
+Test on table
+create table t1(sqlmode varchar(10),ord int,act varchar(10),c1 varchar(10),c2 varchar(10), c3 varchar(10), i1 int,i2 int);
+insert into t1 values ('ORACLE',1,'substr','abc', null,null, 0,    2);
+insert into t1 values ('ORACLE',0,'substr','abc', null,null, 0,    0);
+insert into t1 values ('ORACLE',2,'substr',''   , null,null, 0,    2);
+insert into t1 values ('ORACLE',3,'substr','abc', null,null, 0,    2);
+insert into t1 values ('ORACLE',4,'substr','abc', null,null, 10,   2);
+insert into t1 values ('ORACLE',5,'substr','abc', null,null, 1,    0);
+insert into t1 values ('ORACLE',1,'lpad',  '',    ' ', null, 10,   null);
+insert into t1 values ('ORACLE',2,'lpad',  '',    '',  null, 10,   null);
+insert into t1 values ('ORACLE',3,'lpad',  'x',   '',  null, 10,   null);
+insert into t1 values ('ORACLE',3,'lpad',  'x',   ' ', null,  0,    null);
+insert into t1 values ('ORACLE',1,'rpad',  '',    ' ', null, 10,   null);
+insert into t1 values ('ORACLE',3,'rpad',  '',    '',  null, 10,   null);
+insert into t1 values ('ORACLE',4,'rpad',  'x',   '',  null, 10,   null);
+insert into t1 values ('ORACLE',3,'rpad',  'x',   ' ', null,  0,    null);
+insert into t1 values ('ORACLE',1,'trim',  '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'rtrim', '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'ltrim', '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'length','',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'instr', 'abc', '',  null, null, null);
+insert into t1 values ('ORACLE',2,'instr', '',    '',  null, null, null);
+insert into t1 values ('ORACLE',2,'instr', '',    'b', null, null, null);
+insert into t1 values ('ORACLE',1,'ascii', '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'cast',  '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'concat','',    '',  null, null, null);
+insert into t1 values ('ORACLE',1,'replace','aa', 'a', null, null, null);
+insert into t1 values ('ORACLE',1,'replace','aax','a', 'c' , null, null);
+insert into t1 values ('ORACLE',1,'replace',null, 'a', 'c' , null, null);
+set sql_mode=default;
+insert into t1 values ('DEFAULT',1,'concat','',    '',  '',  null, null);
+set sql_mode=oracle;
+select sqlmode||' '||act||'('||c1||','||i1||','||i2||')',nvl(substr(c1,i1,i2),'is null')  from t1 where act='substr' and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||i1||','||i2||')'	nvl(substr(c1,i1,i2),'is null')
+ORACLE substr(abc,0,0)	is null
+ORACLE substr(abc,0,2)	ab
+ORACLE substr(,0,2)	is null
+ORACLE substr(abc,0,2)	ab
+ORACLE substr(abc,10,2)	is null
+ORACLE substr(abc,1,0)	is null
+select sqlmode||' '||act||'('||c1||','||i1||','||c2||')',nvl(lpad(c1,i1,c2),'is null')    from t1 where act='lpad'   and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||i1||','||c2||')'	nvl(lpad(c1,i1,c2),'is null')
+ORACLE lpad(,10, )	is null
+ORACLE lpad(,10,)	is null
+ORACLE lpad(x,10,)	is null
+ORACLE lpad(x,0, )	is null
+select sqlmode||' '||act||'('||c1||','||i1||','||c2||')',nvl(rpad(c1,i1,c2),'is null')    from t1 where act='rpad'   and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||i1||','||c2||')'	nvl(rpad(c1,i1,c2),'is null')
+ORACLE rpad(,10, )	is null
+ORACLE rpad(,10,)	is null
+ORACLE rpad(x,0, )	is null
+ORACLE rpad(x,10,)	is null
+select sqlmode||' '||act||'('||c1||')',nvl(trim(c1),'is null')                            from t1 where act='trim'   and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||')'	nvl(trim(c1),'is null')
+ORACLE trim()	is null
+select sqlmode||' '||act||'('||c1||')',nvl(ltrim(c1),'is null')                           from t1 where act='ltrim'  and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||')'	nvl(ltrim(c1),'is null')
+ORACLE ltrim()	is null
+select sqlmode||' '||act||'('||c1||')',nvl(rtrim(c1),'is null')                           from t1 where act='rtrim'  and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||')'	nvl(rtrim(c1),'is null')
+ORACLE rtrim()	is null
+select sqlmode||' '||act||'('||c1||')',nvl(length(c1),-1)                                 from t1 where act='length' and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||')'	nvl(length(c1),-1)
+ORACLE length()	-1
+select sqlmode||' '||act||'('||c1||','||c2||')',nvl(instr(c1,c2),'is null')               from t1 where act='instr'  and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||c2||')'	nvl(instr(c1,c2),'is null')
+ORACLE instr(abc,)	is null
+ORACLE instr(,)	is null
+ORACLE instr(,b)	is null
+select sqlmode||' '||act||'('||c1||')',nvl(ascii(c1),-1)                                  from t1 where act='ascii'  and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||')'	nvl(ascii(c1),-1)
+ORACLE ascii()	-1
+select sqlmode||' '||act||'('||c1||')',nvl(cast(c1 as int),-1)                            from t1 where act='cast'   and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||')'	nvl(cast(c1 as int),-1)
+ORACLE cast()	-1
+select sqlmode||' '||act||'('||c1||','||c2||')',nvl(concat(c1,c2),'is null')              from t1 where act='concat' and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||c2||')'	nvl(concat(c1,c2),'is null')
+ORACLE concat(,)	is null
+select sqlmode||' '||act||'('||c1||','||c2||','||c3||')',nvl(replace(c1,c2,c3),'is null') from t1 where act='replace' and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||c2||','||c3||')'	nvl(replace(c1,c2,c3),'is null')
+ORACLE replace(aa,a,)	is null
+ORACLE replace(aax,a,c)	ccx
+ORACLE replace(,a,c)	is null
+rpad/lpad with 2 args
+select rpad('x',10),length(rpad('x',10)),
+lpad('y',15),length(lpad('y',15));
+rpad('x',10)	length(rpad('x',10))	lpad('y',15)	length(lpad('y',15))
+x         	10	              y	15
+rpad/lpad with 3 args
+select rpad('x',10,'.'),length(rpad('x',10,'.')),
+lpad('y',15,'.'),length(lpad('y',15,'.'));
+rpad('x',10,'.')	length(rpad('x',10,'.'))	lpad('y',15,'.')	length(lpad('y',15,'.'))
+x.........	10	..............y	15
+set sql_mode=default;
+select rpad('x',10,'.'),length(rpad('x',10,'.')),
+lpad('y',15,'.'),length(lpad('y',15,'.'));
+rpad('x',10,'.')	length(rpad('x',10,'.'))	lpad('y',15,'.')	length(lpad('y',15,'.'))
+x.........	10	..............y	15
+set sql_mode=oracle;
+select sqlmode||' '||act||'('||c1||','||i1||')',nvl(lpad(c1,i1),'is null'),length(lpad(c1,i1))
+from t1 where act='lpad'   and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||i1||')'	nvl(lpad(c1,i1),'is null')	length(lpad(c1,i1))
+ORACLE lpad(,10)	is null	NULL
+ORACLE lpad(,10)	is null	NULL
+ORACLE lpad(x,10)	         x	10
+ORACLE lpad(x,0)	is null	NULL
+select sqlmode||' '||act||'('||c1||','||i1||')',nvl(rpad(c1,i1),'is null'),length(rpad(c1,i1))
+from t1 where act='rpad'   and sqlmode='ORACLE' order by ord;
+sqlmode||' '||act||'('||c1||','||i1||')'	nvl(rpad(c1,i1),'is null')	length(rpad(c1,i1))
+ORACLE rpad(,10)	is null	NULL
+ORACLE rpad(,10)	is null	NULL
+ORACLE rpad(x,0)	is null	NULL
+ORACLE rpad(x,10)	x         	10
+select count(*) from t1 where c1='';
+count(*)
+0
+select count(*) from t1 where c1!='';
+count(*)
+0
+select count(*) from t1 where c1 is null;
+count(*)
+15
+select count(*) from t1 where c1 is not null;
+count(*)
+13
+select count(*) from t1 where c2 is null;
+count(*)
+19
+select count(*) from t1 where c2 is not null;
+count(*)
+9
+select count(*) from t1 where c1=c2;
+count(*)
+1
+select count(*) from t1 where c1!=c2;
+count(*)
+4
+Ways to select null and empty string in Oracle mode
+select * from t1 where substr(c1,1) is null and sqlmode='DEFAULT';
+sqlmode	ord	act	c1	c2	c3	i1	i2
+DEFAULT	1	concat				NULL	NULL
+select * from t1 where trim(c1) is null and sqlmode='DEFAULT';
+sqlmode	ord	act	c1	c2	c3	i1	i2
+DEFAULT	1	concat				NULL	NULL
+select * from t1 where rtrim(c1) is null and sqlmode='DEFAULT';
+sqlmode	ord	act	c1	c2	c3	i1	i2
+DEFAULT	1	concat				NULL	NULL
+select * from t1 where ltrim(c1) is null and sqlmode='DEFAULT';
+sqlmode	ord	act	c1	c2	c3	i1	i2
+DEFAULT	1	concat				NULL	NULL
+Ways to only select empty string in Oracle mode
+select * from t1 where length(c1)=0 and sqlmode='DEFAULT';
+sqlmode	ord	act	c1	c2	c3	i1	i2
+DEFAULT	1	concat				NULL	NULL
+select * from t1 where ascii(c1)=0 and sqlmode='DEFAULT';
+sqlmode	ord	act	c1	c2	c3	i1	i2
+DEFAULT	1	concat				NULL	NULL
+drop table t1;
+# test in procedure
+CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS
+BEGIN
+SET p1='p1new';
+SET p2='';
+END;
+/
+SET @p1='p1', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+@p1	@p2
+p1	NULL
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS
+BEGIN
+SET p2=rtrim(p1);
+END;
+/
+SET @p1='  ', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+@p1	@p2
+  	NULL
+set sql_mode=default;
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+@p1	@p2
+  	NULL
+DROP PROCEDURE p1;
+set sql_mode=oracle;
+CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS
+BEGIN
+p2:=coalesce(p1,'p1 is null');
+END;
+/
+SET @p1='', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+@p1	@p2
+NULL	p1 is null
+set sql_mode=default;
+SET @p1='', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+@p1	@p2
+	
+DROP PROCEDURE p1;
+set sql_mode=oracle;
+create table t1 (a int,b varchar(10));
+insert into t1 values (1,'one'),(2, 'two'),(3,'three');
+prepare test from 'select a from t1 where coalesce(?,''two'')=''two''';
+set @param='one';
+execute test using @param;
+a
+set @param='';
+execute test using @param;
+a
+1
+2
+3
+set sql_mode=default;
+set @param='';
+set sql_mode=oracle;
+execute test using @param;
+a
+drop table t1;
diff --git a/mysql-test/suite/compat/oracle/r/func_concat.result b/mysql-test/suite/compat/oracle/r/func_concat.result
index 230b36b..565fcae 100644
--- a/mysql-test/suite/compat/oracle/r/func_concat.result
+++ b/mysql-test/suite/compat/oracle/r/func_concat.result
@@ -11,13 +11,13 @@ Warnings:
 Note	1003	select concat_operator_oracle(concat_operator_oracle(concat_operator_oracle('a','b'),'c')) AS "CONCAT('a'||'b'||'c')"
 SELECT ''   || '';
 ''   || ''
-
+NULL
 SELECT ''   || 'b';
 ''   || 'b'
 b
 SELECT ''   || NULL;
 ''   || NULL
-
+NULL
 SELECT 'a'  || '';
 'a'  || ''
 a
@@ -29,7 +29,7 @@ SELECT 'a'  || NULL;
 a
 SELECT NULL || '';
 NULL || ''
-
+NULL
 SELECT NULL || 'b';
 NULL || 'b'
 b
@@ -38,13 +38,13 @@ NULL || NULL
 NULL
 SELECT ''   || ''    || '';
 ''   || ''    || ''
-
+NULL
 SELECT ''   || ''    || 'c';
 ''   || ''    || 'c'
 c
 SELECT ''   || ''    || NULL;
 ''   || ''    || NULL
-
+NULL
 SELECT ''   || 'b'   || '';
 ''   || 'b'   || ''
 b
@@ -56,13 +56,13 @@ SELECT ''   || 'b'   || NULL;
 b
 SELECT ''   || NULL  || '';
 ''   || NULL  || ''
-
+NULL
 SELECT ''   || NULL  || 'c';
 ''   || NULL  || 'c'
 c
 SELECT ''   || NULL  || NULL;
 ''   || NULL  || NULL
-
+NULL
 SELECT 'a'  || ''    || '';
 'a'  || ''    || ''
 a
@@ -92,13 +92,13 @@ SELECT 'a'  || NULL  || NULL;
 a
 SELECT NULL || ''    || '';
 NULL || ''    || ''
-
+NULL
 SELECT NULL || ''    || 'c';
 NULL || ''    || 'c'
 c
 SELECT NULL || ''    || NULL;
 NULL || ''    || NULL
-
+NULL
 SELECT NULL || 'b'   || '';
 NULL || 'b'   || ''
 b
@@ -110,7 +110,7 @@ NULL || 'b'   || NULL
 b
 SELECT NULL || NULL  || '';
 NULL || NULL  || ''
-
+NULL
 SELECT NULL || NULL  || 'c';
 NULL || NULL  || 'c'
 c
@@ -148,58 +148,58 @@ 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
 NULL	NULL
-0	
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
 1	c
-0	
-0	
 1	c
-1	b
-1	b
-2	bc
-0	
-0	
 1	c
-0	
-0	
 1	c
 1	b
 1	b
+1	b
+1	b
+2	bc
 2	bc
 1	a
 1	a
-2	ac
 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)
 NULL	NULL
-0	
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
+NULL	NULL
 1	c
-0	
-0	
 1	c
-1	b
-1	b
-2	bc
-0	
-0	
 1	c
-0	
-0	
 1	c
 1	b
 1	b
+1	b
+1	b
+2	bc
 2	bc
 1	a
 1	a
-2	ac
 1	a
 1	a
 2	ac
+2	ac
 2	ab
 2	ab
 3	abc
diff --git a/mysql-test/suite/compat/oracle/r/func_substr.result b/mysql-test/suite/compat/oracle/r/func_substr.result
index eca5f48..81dfd0d 100644
--- a/mysql-test/suite/compat/oracle/r/func_substr.result
+++ b/mysql-test/suite/compat/oracle/r/func_substr.result
@@ -22,7 +22,7 @@ SUBSTR('abc',2,null)	SUBSTR('abc',1,null)	SUBSTR('abc',0,null)
 NULL	NULL	NULL
 SELECT SUBSTR('abc',2,0),SUBSTR('abc',1,0), SUBSTR('abc',0,0) FROM dual;
 SUBSTR('abc',2,0)	SUBSTR('abc',1,0)	SUBSTR('abc',0,0)
-		
+NULL	NULL	NULL
 create table t1 (c1 varchar(10),start integer, length integer);
 INSERT INTO t1 VALUES ('abc', 1, 1);
 INSERT INTO t1 VALUES ('abc', 0, 1);
diff --git a/mysql-test/suite/compat/oracle/t/empty-string.test b/mysql-test/suite/compat/oracle/t/empty-string.test
new file mode 100644
index 0000000..3b7869e
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/empty-string.test
@@ -0,0 +1,237 @@
+use test;
+--echo #
+--echo # MDEV-10574 sql_mode=ORACLE: IS NULL and empty strings
+--echo #
+set session character_set_connection=latin2;
+set session character_set_client=cp1250;
+--echo Test litteral
+SET sql_mode=ORACLE;
+select '',charset(''), null, charset(null), cast(null as varchar(10)), charset(cast(null as varchar(10))), 'x', charset('x');
+SET sql_mode=default;
+select '',charset(''), null, charset(null), cast(null as char(10)), charset(cast(null as char(10))), 'x', charset('x');
+
+--echo Test NCHAR litteral
+SET sql_mode=ORACLE;
+select N'',charset(N''), N'x', charset(N'x');
+SET sql_mode=default;
+select N'',charset(N''), N'x', charset(N'x');
+
+--echo Test charset prefix litteral
+SET sql_mode=ORACLE;
+select _cp1250 '',charset(_cp1250 ''), _cp1250 'x', charset(_cp1250 'x');
+SET sql_mode=default;
+select _cp1250 '',charset(_cp1250 ''), _cp1250 'x', charset(_cp1250 'x');
+
+SET sql_mode=ORACLE;
+--echo Test of basic string function that must return null with '' in input
+
+select nvl(ascii(''),-1) from dual;
+select nvl(cast('' as int),-1) from dual;
+select concat('','x'),nvl(concat('',''),'is null') from dual;
+select nvl(instr('abc',''),-1) from dual;
+select nvl(instr('',''),-1) from dual;
+select nvl(instr('','b'),-1) from dual;
+select nvl(left('a',0),'is null') from dual;
+select nvl(length(''),-1) from dual;
+
+select nvl(lpad('',10,' '),'is null'),
+       nvl(lpad('',10,''),'is null'),
+       nvl(lpad('x',10,''),'is null'),
+       nvl(lpad('x',0,' '),'is null')
+  from dual;
+
+select nvl(mid('abc',1,0),'is null') from dual;
+select nvl(mid('abc',10,1),'is null') from dual;
+select nvl(right('a',0),'is null') from dual;
+
+select nvl(rpad('',10,' '),'is null'),
+       nvl(rpad('',10,''),'is null'),
+       nvl(rpad('x',10,''),'is null'),
+       nvl(rpad('x',0,' '),'is null')
+  from dual;
+
+select nvl(replace('abc','a',''),'is null'),
+       nvl(replace('abc','','x'),'is null'),
+       nvl(replace('','a','b'),'is null'),
+       nvl(replace('','','b'),'is null'),
+       nvl(replace('','',''),'is null'),
+       nvl(replace('aaa','a',null),'is null')
+  from dual;
+
+select nvl(substr('abc',1,0),'is null'),
+       nvl(substr('abc',10,2),'is null'),
+       nvl(substr('abc',0,2),'is null')
+  from dual;
+
+--echo Test substr with start at 0
+select nvl(substr('abc',0,0),'is null'),
+       nvl(substr('abc',0,2),'is null'),
+       nvl(substr('',0,2),'is null')
+  from dual;
+
+select nvl(trim(''),'is null'),
+       nvl(rtrim(''),'is null'),
+       nvl(ltrim(''),'is null') from dual;
+
+--echo Test default on column
+create table t1 (c1 varchar(10) default '');
+show create table t1;
+drop table t1;
+
+--echo Test on table
+create table t1(sqlmode varchar(10),ord int,act varchar(10),c1 varchar(10),c2 varchar(10), c3 varchar(10), i1 int,i2 int);
+insert into t1 values ('ORACLE',1,'substr','abc', null,null, 0,    2);
+insert into t1 values ('ORACLE',0,'substr','abc', null,null, 0,    0);
+insert into t1 values ('ORACLE',2,'substr',''   , null,null, 0,    2);
+insert into t1 values ('ORACLE',3,'substr','abc', null,null, 0,    2);
+insert into t1 values ('ORACLE',4,'substr','abc', null,null, 10,   2);
+insert into t1 values ('ORACLE',5,'substr','abc', null,null, 1,    0);
+insert into t1 values ('ORACLE',1,'lpad',  '',    ' ', null, 10,   null);
+insert into t1 values ('ORACLE',2,'lpad',  '',    '',  null, 10,   null);
+insert into t1 values ('ORACLE',3,'lpad',  'x',   '',  null, 10,   null);
+insert into t1 values ('ORACLE',3,'lpad',  'x',   ' ', null,  0,    null);
+insert into t1 values ('ORACLE',1,'rpad',  '',    ' ', null, 10,   null);
+insert into t1 values ('ORACLE',3,'rpad',  '',    '',  null, 10,   null);
+insert into t1 values ('ORACLE',4,'rpad',  'x',   '',  null, 10,   null);
+insert into t1 values ('ORACLE',3,'rpad',  'x',   ' ', null,  0,    null);
+insert into t1 values ('ORACLE',1,'trim',  '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'rtrim', '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'ltrim', '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'length','',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'instr', 'abc', '',  null, null, null);
+insert into t1 values ('ORACLE',2,'instr', '',    '',  null, null, null);
+insert into t1 values ('ORACLE',2,'instr', '',    'b', null, null, null);
+insert into t1 values ('ORACLE',1,'ascii', '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'cast',  '',    null,null, null, null);
+insert into t1 values ('ORACLE',1,'concat','',    '',  null, null, null);
+insert into t1 values ('ORACLE',1,'replace','aa', 'a', null, null, null);
+insert into t1 values ('ORACLE',1,'replace','aax','a', 'c' , null, null);
+insert into t1 values ('ORACLE',1,'replace',null, 'a', 'c' , null, null);
+set sql_mode=default;
+insert into t1 values ('DEFAULT',1,'concat','',    '',  '',  null, null);
+set sql_mode=oracle;
+
+select sqlmode||' '||act||'('||c1||','||i1||','||i2||')',nvl(substr(c1,i1,i2),'is null')  from t1 where act='substr' and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||','||i1||','||c2||')',nvl(lpad(c1,i1,c2),'is null')    from t1 where act='lpad'   and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||','||i1||','||c2||')',nvl(rpad(c1,i1,c2),'is null')    from t1 where act='rpad'   and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||')',nvl(trim(c1),'is null')                            from t1 where act='trim'   and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||')',nvl(ltrim(c1),'is null')                           from t1 where act='ltrim'  and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||')',nvl(rtrim(c1),'is null')                           from t1 where act='rtrim'  and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||')',nvl(length(c1),-1)                                 from t1 where act='length' and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||','||c2||')',nvl(instr(c1,c2),'is null')               from t1 where act='instr'  and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||')',nvl(ascii(c1),-1)                                  from t1 where act='ascii'  and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||')',nvl(cast(c1 as int),-1)                            from t1 where act='cast'   and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||','||c2||')',nvl(concat(c1,c2),'is null')              from t1 where act='concat' and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||','||c2||','||c3||')',nvl(replace(c1,c2,c3),'is null') from t1 where act='replace' and sqlmode='ORACLE' order by ord;
+
+
+--echo rpad/lpad with 2 args
+select rpad('x',10),length(rpad('x',10)),
+       lpad('y',15),length(lpad('y',15));
+
+--echo rpad/lpad with 3 args
+select rpad('x',10,'.'),length(rpad('x',10,'.')),
+       lpad('y',15,'.'),length(lpad('y',15,'.'));
+set sql_mode=default;
+select rpad('x',10,'.'),length(rpad('x',10,'.')),
+       lpad('y',15,'.'),length(lpad('y',15,'.'));
+
+set sql_mode=oracle;
+
+select sqlmode||' '||act||'('||c1||','||i1||')',nvl(lpad(c1,i1),'is null'),length(lpad(c1,i1))
+  from t1 where act='lpad'   and sqlmode='ORACLE' order by ord;
+select sqlmode||' '||act||'('||c1||','||i1||')',nvl(rpad(c1,i1),'is null'),length(rpad(c1,i1))
+  from t1 where act='rpad'   and sqlmode='ORACLE' order by ord;
+
+select count(*) from t1 where c1='';
+select count(*) from t1 where c1!='';
+select count(*) from t1 where c1 is null;
+select count(*) from t1 where c1 is not null;
+select count(*) from t1 where c2 is null;
+select count(*) from t1 where c2 is not null;
+select count(*) from t1 where c1=c2;
+select count(*) from t1 where c1!=c2;
+
+--echo Ways to select null and empty string in Oracle mode
+select * from t1 where substr(c1,1) is null and sqlmode='DEFAULT';
+select * from t1 where trim(c1) is null and sqlmode='DEFAULT';
+select * from t1 where rtrim(c1) is null and sqlmode='DEFAULT';
+select * from t1 where ltrim(c1) is null and sqlmode='DEFAULT';
+
+--echo Ways to only select empty string in Oracle mode
+select * from t1 where length(c1)=0 and sqlmode='DEFAULT';
+select * from t1 where ascii(c1)=0 and sqlmode='DEFAULT';
+
+drop table t1;
+
+--echo # test in procedure
+
+DELIMITER /;
+CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS
+BEGIN
+  SET p1='p1new';
+  SET p2='';
+END;
+/
+DELIMITER ;/
+SET @p1='p1', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+DROP PROCEDURE p1;
+DELIMITER /;
+CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS
+BEGIN
+  SET p2=rtrim(p1);
+END;
+/
+DELIMITER ;/
+SET @p1='  ', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+
+set sql_mode=default;
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+DROP PROCEDURE p1;
+
+set sql_mode=oracle;
+DELIMITER /;
+CREATE PROCEDURE p1 (p1 IN VARCHAR2(10), p2 OUT VARCHAR2(10)) AS
+BEGIN
+  p2:=coalesce(p1,'p1 is null');
+END;
+/
+DELIMITER ;/
+SET @p1='', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+
+# Mix mod : bind param is set to an empty string in default mode and execute
+# is done in oracle mode.
+# Wrong result : parameter p1 is not null inside procedure p1
+set sql_mode=default;
+SET @p1='', @p2='p2';
+CALL p1(@p1, @p2);
+SELECT @p1, @p2;
+
+DROP PROCEDURE p1;
+
+set sql_mode=oracle;
+create table t1 (a int,b varchar(10));
+insert into t1 values (1,'one'),(2, 'two'),(3,'three');
+prepare test from 'select a from t1 where coalesce(?,''two'')=''two''';
+set @param='one';
+execute test using @param;
+set @param='';
+execute test using @param;
+
+# Mix mod : bind param is set to an empty string in default mode and execute
+# is done in oracle mode.
+# Wrong result (empty set).
+
+set sql_mode=default;
+set @param='';
+set sql_mode=oracle;
+execute test using @param;
+
+drop table t1;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index e54b29f..e5ab945 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -140,6 +140,33 @@ longlong Item_str_func::val_int()
 }
 
 
+/**
+    Sets the result value of the function an empty string, using the current
+    character set. No memory is allocated.
+    Sets result value to null when sql_mode=oracle.
+    @retval A pointer to the str_value member.
+  */
+String *Item_str_func::make_empty_result()
+{
+  /*
+    Reset string length to an empty string. We don't use str_value.set() as
+    we don't want to free and potentially have to reallocate the buffer
+    for each call.
+  */
+  str_value.set_charset(collation.collation);
+  if (!(current_thd->variables.sql_mode & MODE_ORACLE))
+  {
+    str_value.length(0);
+    return &str_value;
+  }
+  else
+  {
+    null_value= 1;
+    return NULL;
+  }
+}
+
+
 String *Item_func_md5::val_str_ascii(String *str)
 {
   DBUG_ASSERT(fixed == 1);
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index f10d685..72d3e02 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -37,17 +37,7 @@ class Item_str_func :public Item_func
      character set. No memory is allocated.
      @retval A pointer to the str_value member.
    */
-  String *make_empty_result()
-  {
-    /*
-      Reset string length to an empty string. We don't use str_value.set() as
-      we don't want to free and potentially have to reallocate the buffer
-      for each call.
-    */
-    str_value.length(0);
-    str_value.set_charset(collation.collation);
-    return &str_value; 
-  }
+  String *make_empty_result();
 public:
   Item_str_func(THD *thd): Item_func(thd) { decimals=NOT_FIXED_DEC; }
   Item_str_func(THD *thd, Item *a): Item_func(thd, a) {decimals=NOT_FIXED_DEC; }
@@ -557,6 +547,9 @@ class Item_func_trim :public Item_str_func
   String remove;
   String *trimmed_value(String *res, uint32 offset, uint32 length)
   {
+    if (length == 0)
+      return make_empty_result();
+
     tmp_value.set(*res, offset, length);
     /*
       Make sure to return correct charset and collation:
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 4b03a57..f1cbf40 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -7193,6 +7193,86 @@ bool LEX::add_grant_command(THD *thd, enum_sql_command sql_command_arg,
 }
 
 
+Item *LEX::make_text_literal(THD *thd, const Lex_string_with_metadata_st &text)
+{
+  if (text.length == 0 && (thd->variables.sql_mode & MODE_ORACLE))
+    return new (thd->mem_root) Item_null(thd, 0,
+                                         thd->variables.collation_connection);
+
+  return thd->make_string_literal(text);
+}
+
+
+Item *LEX::make_text_literal_nchar(THD *thd,
+                                   const Lex_string_with_metadata_st &text)
+{
+  DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
+  if (text.length == 0 && (thd->variables.sql_mode & MODE_ORACLE))
+    return new (thd->mem_root) Item_null(thd, 0, national_charset_info);
+
+  return new (thd->mem_root) Item_string(thd,
+                                         text.str,
+                                         text.length,
+                                         national_charset_info,
+                                         DERIVATION_COERCIBLE,
+                                         text.repertoire());
+}
+
+
+Item *LEX::make_text_literal_charset(THD *thd,
+                                     CHARSET_INFO *charset,
+                                     const Lex_string_with_metadata_st &text)
+{
+  if (text.length == 0 && (thd->variables.sql_mode & MODE_ORACLE))
+    return new (thd->mem_root) Item_null(thd, 0, charset);
+  else
+    return new (thd->mem_root) Item_string_with_introducer(thd,
+                                                           text.str,
+                                                           text.length,
+                                                           charset);
+}
+
+
+Item *LEX::make_text_literal_concat(THD *thd, Item *item1, const LEX_CSTRING &text)
+{
+  Item_string *item= (Item_string *) item1;
+  if (item->type() != Item::NULL_ITEM ||
+     !(thd->variables.sql_mode & MODE_ORACLE))
+  {
+    item->append(text.str, text.length);
+    if (!(item->collation.repertoire & MY_REPERTOIRE_EXTENDED))
+    {
+      /*
+          If the string has been pure ASCII so far,
+          check the new part.
+      */
+      CHARSET_INFO *cs= thd->variables.collation_connection;
+      item->collation.repertoire|= my_string_repertoire(cs,
+                                                        text.str,
+                                                        text.length);
+    }
+    return item;
+  }
+  else
+  {
+    if (text.length == 0)
+      return item1;
+    else
+    {
+      CHARSET_INFO *cs_con= thd->variables.collation_connection;
+      CHARSET_INFO *cs_cli= thd->variables.character_set_client;
+      uint repertoire= my_string_repertoire(cs_cli, text.str, text.length);
+      return new (thd->mem_root) Item_string(thd,
+                                             text.str,
+                                             text.length,
+                                             item1->collation.collation,
+                                             DERIVATION_COERCIBLE,
+                                             repertoire);
+    }
+  }
+}
+
+
 Item *LEX::make_item_func_substr(THD *thd, Item *a, Item *b, Item *c)
 {
   return (thd->variables.sql_mode & MODE_ORACLE) ?
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ce63c40..bdad3f2 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3362,7 +3362,15 @@ struct LEX: public Query_tables_list
   Item *make_item_func_substr(THD *thd, Item *a, Item *b, Item *c);
   Item *make_item_func_substr(THD *thd, Item *a, Item *b);
   Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace);
-
+  Item *make_text_literal(THD *thd,
+                          const Lex_string_with_metadata_st &text);
+  Item *make_text_literal_nchar(THD *thd,
+                                const Lex_string_with_metadata_st &text);
+  Item *make_text_literal_charset(THD *thd,
+                                  CHARSET_INFO *charset,
+                                  const Lex_string_with_metadata_st &text);
+  Item *make_text_literal_concat(THD *thd, Item *item1,
+                                 const LEX_CSTRING &text);
   /*
     Create a my_var instance for a ROW field variable that was used
     as an OUT SP parameter: CALL p1(var.field);
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index f83df07..f9292f6 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -734,6 +734,33 @@ static void set_param_str(Item_param *param, uchar **pos, ulong len)
   *pos+= length;
 }
 
+/*
+  set_param_str_oracle : convert empty string to null value
+  This allow to bind empty string in JDBC as a null value.
+  Ex :
+    String sel="select coalesce(?,'null param') from dual";
+    PreparedStatement ps_sel = m_cnx.prepareStatement(sel);
+    ps_sel.setString(1, "");
+    ResultSet rs = ps_sel.executeQuery();
+    while (rs.next())
+    {
+       System.out.println(rs.getString(1));
+    }
+  Returns : 'null param'
+*/
+static void set_param_str_oracle(Item_param *param, uchar **pos, ulong len)
+{
+  ulong length= get_param_length(pos, len);
+  if (length == 0)
+    param->set_null();
+  else
+  {
+    if (length > len)
+      length= len;
+    param->set_str((const char *) *pos, length);
+    *pos+= length;
+  }
+}
 
 #undef get_param_length
 
@@ -806,7 +833,10 @@ static void setup_one_conversion_function(THD *thd, Item_param *param,
       param->value.cs_info.final_character_set_of_str_value=
         String::needs_conversion(0, fromcs, tocs, &dummy_offset) ?
         tocs : fromcs;
-      param->set_param_func= set_param_str;
+      if (thd->variables.sql_mode & MODE_ORACLE)
+        param->set_param_func= set_param_str_oracle;
+      else
+        param->set_param_func= set_param_str;
       /*
         Exact value of max_length is not known unless data is converted to
         charset of connection, so we have to set it later.
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c57e046..d84c2ff 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -13830,43 +13830,25 @@ load_data_set_elem:
 /* Common definitions */
 
 text_literal:
-          TEXT_STRING
+         TEXT_STRING
           {
-            if (!($$= thd->make_string_literal($1)))
+            if (!($$= Lex->make_text_literal(thd, $1)))
               MYSQL_YYABORT;
           }
         | NCHAR_STRING
           {
-            DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
-            $$= new (thd->mem_root) Item_string(thd, $1.str, $1.length,
-                                                  national_charset_info,
-                                                  DERIVATION_COERCIBLE,
-                                                  $1.repertoire());
-            if ($$ == NULL)
+            if (!($$= Lex->make_text_literal_nchar(thd, $1)))
               MYSQL_YYABORT;
           }
         | UNDERSCORE_CHARSET TEXT_STRING
           {
-            $$= new (thd->mem_root) Item_string_with_introducer(thd, $2.str,
-                                                                $2.length, $1);
-            if ($$ == NULL)
+            if (!($$= Lex->make_text_literal_charset(thd, $1, $2)))
               MYSQL_YYABORT;
           }
         | text_literal TEXT_STRING_literal
           {
-            Item_string* item= (Item_string*) $1;
-            item->append($2.str, $2.length);
-            if (!(item->collation.repertoire & MY_REPERTOIRE_EXTENDED))
-            {
-              /*
-                 If the string has been pure ASCII so far,
-                 check the new part.
-              */
-              CHARSET_INFO *cs= thd->variables.collation_connection;
-              item->collation.repertoire|= my_string_repertoire(cs,
-                                                                $2.str,
-                                                                $2.length);
-            }
+            if (!($$= Lex->make_text_literal_concat(thd, $1, $2)))
+              MYSQL_YYABORT;
           }
         ;
 
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index 1fe9429..4cd1924 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -13920,41 +13920,23 @@ load_data_set_elem:
 text_literal:
           TEXT_STRING
           {
-            if (!($$= thd->make_string_literal($1)))
+            if (!($$= Lex->make_text_literal(thd, $1)))
               MYSQL_YYABORT;
           }
         | NCHAR_STRING
           {
-            DBUG_ASSERT(my_charset_is_ascii_based(national_charset_info));
-            $$= new (thd->mem_root) Item_string(thd, $1.str, $1.length,
-                                                  national_charset_info,
-                                                  DERIVATION_COERCIBLE,
-                                                  $1.repertoire());
-            if ($$ == NULL)
+            if (!($$= Lex->make_text_literal_nchar(thd, $1)))
               MYSQL_YYABORT;
           }
         | UNDERSCORE_CHARSET TEXT_STRING
           {
-            $$= new (thd->mem_root) Item_string_with_introducer(thd, $2.str,
-                                                                $2.length, $1);
-            if ($$ == NULL)
+            if (!($$= Lex->make_text_literal_charset(thd, $1, $2)))
               MYSQL_YYABORT;
           }
         | text_literal TEXT_STRING_literal
           {
-            Item_string* item= (Item_string*) $1;
-            item->append($2.str, $2.length);
-            if (!(item->collation.repertoire & MY_REPERTOIRE_EXTENDED))
-            {
-              /*
-                 If the string has been pure ASCII so far,
-                 check the new part.
-              */
-              CHARSET_INFO *cs= thd->variables.collation_connection;
-              item->collation.repertoire|= my_string_repertoire(cs,
-                                                                $2.str,
-                                                                $2.length);
-            }
+            if (!($$= Lex->make_text_literal_concat(thd, $1, $2)))
+              MYSQL_YYABORT;
           }
         ;
 
