Commit a699a5f9 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT

parent ccb91eb3
......@@ -348,3 +348,5 @@ CREATE TABLE varchar2 (varchar2 int);
DROP TABLE varchar2;
CREATE TABLE decode (decode int);
DROP TABLE decode;
CREATE TABLE rowcount (rowcount int);
DROP TABLE rowcount;
......@@ -28,6 +28,6 @@ EXPLAIN EXTENDED SELECT DECODE(12,10,'x10',11,'x11','def');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
Note 1003 select (case 12 when 10 then 'x10' when 11 then 'x11' else 'def' end) AS "DECODE(12,10,'x10',11,'x11','def')"
Note 1003 select case 12 when 10 then 'x10' when 11 then 'x11' else 'def' end AS "DECODE(12,10,'x10',11,'x11','def')"
CREATE TABLE decode (decode int);
DROP TABLE decode;
......@@ -1066,3 +1066,177 @@ END$$
CALL p1;
ERROR 42S22: Unknown column 'unknown_ident' in 'field list'
DROP PROCEDURE p1;
#
# MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT
#
EXPLAIN EXTENDED SELECT sql%rowcount;
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 SQL%%ROWCOUNT AS "sql%rowcount"
CREATE TABLE t1 AS SELECT SQL%ROWCOUNT;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE "t1" (
"SQL%ROWCOUNT" bigint(21) NOT NULL
)
DROP TABLE t1;
#
# UPDATE
#
CREATE TABLE t1 (a INT);
CREATE PROCEDURE p1
AS
BEGIN
UPDATE t1 SET a=30;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
0
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
CREATE PROCEDURE p1
AS
BEGIN
UPDATE t1 SET a=30;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
2
DROP PROCEDURE p1;
DROP TABLE t1;
#
# DELETE
#
CREATE TABLE t1 (a INT);
CREATE PROCEDURE p1
AS
BEGIN
DELETE FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
0
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
CREATE PROCEDURE p1
AS
BEGIN
DELETE FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
2
DROP PROCEDURE p1;
DROP TABLE t1;
#
# SELECT ... INTO var FROM ... - one row found
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
CREATE PROCEDURE p1
AS
va INT;
BEGIN
SELECT a INTO va FROM t1 LIMIT 1;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
1
DROP PROCEDURE p1;
DROP TABLE t1;
#
# SELECT ... INTO var FROM ... - no rows found
#
CREATE TABLE t1 (a INT);
CREATE PROCEDURE p1
AS
va INT;
BEGIN
SELECT a INTO va FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
0
Warnings:
Warning 1329 No data - zero rows fetched, selected, or processed
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (a INT);
CREATE PROCEDURE p1
AS
va INT;
BEGIN
SELECT a INTO va FROM t1;
SELECT SQL%ROWCOUNT;
EXCEPTION
WHEN NO_DATA_FOUND THEN SELECT SQL%ROWCOUNT||' (EXCEPTION)';
END;
$$
CALL p1();
SQL%ROWCOUNT||' (EXCEPTION)'
0 (EXCEPTION)
DROP PROCEDURE p1;
DROP TABLE t1;
#
# SELECT ... INTO var FROM ... - multiple rows found
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
CREATE PROCEDURE p1
AS
va INT:=1;
BEGIN
SELECT a INTO va FROM t1;
SELECT SQL%ROWCOUNT;
EXCEPTION
WHEN TOO_MANY_ROWS THEN SELECT SQL%ROWCOUNT||' (EXCEPTION) va='||va;
END;
$$
CALL p1();
SQL%ROWCOUNT||' (EXCEPTION) va='||va
1 (EXCEPTION) va=10
DROP PROCEDURE p1;
DROP TABLE t1;
#
# INSERT INTO t2 SELECT ...
#
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
CREATE PROCEDURE p1
AS
BEGIN
INSERT INTO t2 SELECT * FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
CALL p1();
SQL%ROWCOUNT
2
DROP PROCEDURE p1;
DROP TABLE t1, t2;
#
# End of MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT
#
......@@ -1158,3 +1158,193 @@ DELIMITER ;$$
--error ER_BAD_FIELD_ERROR
CALL p1;
DROP PROCEDURE p1;
--echo #
--echo # MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT
--echo #
EXPLAIN EXTENDED SELECT sql%rowcount;
CREATE TABLE t1 AS SELECT SQL%ROWCOUNT;
SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
--echo # UPDATE
--echo #
CREATE TABLE t1 (a INT);
DELIMITER $$;
CREATE PROCEDURE p1
AS
BEGIN
UPDATE t1 SET a=30;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
DELIMITER $$;
CREATE PROCEDURE p1
AS
BEGIN
UPDATE t1 SET a=30;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # DELETE
--echo #
CREATE TABLE t1 (a INT);
DELIMITER $$;
CREATE PROCEDURE p1
AS
BEGIN
DELETE FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
DELIMITER $$;
CREATE PROCEDURE p1
AS
BEGIN
DELETE FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # SELECT ... INTO var FROM ... - one row found
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
DELIMITER $$;
CREATE PROCEDURE p1
AS
va INT;
BEGIN
SELECT a INTO va FROM t1 LIMIT 1;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # SELECT ... INTO var FROM ... - no rows found
--echo #
CREATE TABLE t1 (a INT);
DELIMITER $$;
CREATE PROCEDURE p1
AS
va INT;
BEGIN
SELECT a INTO va FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
CREATE TABLE t1 (a INT);
DELIMITER $$;
CREATE PROCEDURE p1
AS
va INT;
BEGIN
SELECT a INTO va FROM t1;
SELECT SQL%ROWCOUNT;
EXCEPTION
WHEN NO_DATA_FOUND THEN SELECT SQL%ROWCOUNT||' (EXCEPTION)';
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # SELECT ... INTO var FROM ... - multiple rows found
--echo #
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
DELIMITER $$;
CREATE PROCEDURE p1
AS
va INT:=1;
BEGIN
SELECT a INTO va FROM t1;
SELECT SQL%ROWCOUNT;
EXCEPTION
WHEN TOO_MANY_ROWS THEN SELECT SQL%ROWCOUNT||' (EXCEPTION) va='||va;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1;
--echo #
--echo # INSERT INTO t2 SELECT ...
--echo #
CREATE TABLE t1 (a INT);
CREATE TABLE t2 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
DELIMITER $$;
CREATE PROCEDURE p1
AS
BEGIN
INSERT INTO t2 SELECT * FROM t1;
SELECT SQL%ROWCOUNT;
END;
$$
DELIMITER ;$$
CALL p1();
DROP PROCEDURE p1;
DROP TABLE t1, t2;
--echo #
--echo # End of MDEV-10583 sql_mode=ORACLE: SQL%ROWCOUNT
--echo #
......@@ -244,3 +244,6 @@ DROP TABLE varchar2;
CREATE TABLE decode (decode int);
DROP TABLE decode;
CREATE TABLE rowcount (rowcount int);
DROP TABLE rowcount;
......@@ -6632,6 +6632,21 @@ longlong Item_func_found_rows::val_int()
}
longlong Item_func_oracle_sql_rowcount::val_int()
{
DBUG_ASSERT(fixed == 1);
THD *thd= current_thd;
/*
In case when a query like this:
INSERT a INTO @va FROM t1;
returns multiple rows, SQL%ROWCOUNT should report 1 rather than -1.
*/
longlong rows= thd->get_row_count_func();
return rows != -1 ? rows : // ROW_COUNT()
thd->found_rows(); // FOUND_ROWS()
}
/**
@brief Checks if requested access to function can be granted to user.
If function isn't found yet, it searches function first.
......
......@@ -2599,6 +2599,25 @@ class Item_func_found_rows :public Item_int_func
};
class Item_func_oracle_sql_rowcount :public Item_int_func
{
public:
Item_func_oracle_sql_rowcount(THD *thd): Item_int_func(thd) {}
longlong val_int();
const char *func_name() const { return "SQL%%ROWCOUNT"; }
void print(String *str, enum_query_type query_type)
{
str->append(func_name());
}
bool check_vcol_func_processor(void *arg)
{
return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE);
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_oracle_sql_rowcount>(thd, mem_root, this); }
};
void uuid_short_init();
class Item_func_uuid_short :public Item_int_func
......
......@@ -523,6 +523,7 @@ static SYMBOL symbols[] = {
{ "ROLLUP", SYM(ROLLUP_SYM)},
{ "ROUTINE", SYM(ROUTINE_SYM)},
{ "ROW", SYM(ROW_SYM)},
{ "ROWCOUNT", SYM(ROWCOUNT_SYM)}, /* Oracle-N */
{ "ROWS", SYM(ROWS_SYM)},
{ "ROW_COUNT", SYM(ROW_COUNT_SYM)},
{ "ROW_FORMAT", SYM(ROW_FORMAT_SYM)},
......
......@@ -1409,6 +1409,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ROLLBACK_SYM /* SQL-2003-R */
%token ROLLUP_SYM /* SQL-2003-R */
%token ROUTINE_SYM /* SQL-2003-N */
%token ROWCOUNT_SYM /* Oracle-N */
%token ROW_SYM /* SQL-2003-R */
%token ROWS_SYM /* SQL-2003-R */
%token ROW_COUNT_SYM /* SQL-2003-N */
......@@ -14468,6 +14469,7 @@ keyword_sp:
| ROLE_SYM {}
| ROLLUP_SYM {}
| ROUTINE_SYM {}
| ROWCOUNT_SYM {}
| ROW_COUNT_SYM {}
| ROW_FORMAT_SYM {}
| ROW_SYM {}
......
......@@ -783,6 +783,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token ROLLBACK_SYM /* SQL-2003-R */
%token ROLLUP_SYM /* SQL-2003-R */
%token ROUTINE_SYM /* SQL-2003-N */
%token ROWCOUNT_SYM /* Oracle-N */
%token ROW_SYM /* SQL-2003-R */
%token ROWS_SYM /* SQL-2003-R */
%token ROW_COUNT_SYM /* SQL-2003-N */
......@@ -9075,6 +9076,14 @@ function_call_keyword:
if ($$ == NULL)
MYSQL_YYABORT;
}
| SQL_SYM '%' ROWCOUNT_SYM
{
$$= new (thd->mem_root) Item_func_oracle_sql_rowcount(thd);
if ($$ == NULL)
MYSQL_YYABORT;
Lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_FUNCTION);
Lex->safe_to_cache_query= 0;
}
| TIME_SYM '(' expr ')'
{
$$= new (thd->mem_root) Item_time_typecast(thd, $3,
......@@ -14420,6 +14429,7 @@ keyword_sp:
| ROLE_SYM {}
| ROLLUP_SYM {}
| ROUTINE_SYM {}
| ROWCOUNT_SYM {}
| ROW_COUNT_SYM {}
| ROW_FORMAT_SYM {}
| ROW_SYM {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment