Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
76714a5c
Commit
76714a5c
authored
8 years ago
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND
parent
4bb87996
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
800 additions
and
10 deletions
+800
-10
mysql-test/r/keywords.result
mysql-test/r/keywords.result
+4
-0
mysql-test/suite/compat/oracle/r/sp-cursor.result
mysql-test/suite/compat/oracle/r/sp-cursor.result
+291
-0
mysql-test/suite/compat/oracle/t/sp-cursor.test
mysql-test/suite/compat/oracle/t/sp-cursor.test
+296
-0
mysql-test/t/keywords.test
mysql-test/t/keywords.test
+6
-0
sql/item_func.cc
sql/item_func.cc
+48
-0
sql/item_func.h
sql/item_func.h
+70
-0
sql/lex.h
sql/lex.h
+2
-0
sql/sp_pcontext.cc
sql/sp_pcontext.cc
+3
-1
sql/sp_rcontext.cc
sql/sp_rcontext.cc
+12
-1
sql/sp_rcontext.h
sql/sp_rcontext.h
+13
-1
sql/sql_yacc.yy
sql/sql_yacc.yy
+4
-0
sql/sql_yacc_ora.yy
sql/sql_yacc_ora.yy
+51
-7
No files found.
mysql-test/r/keywords.result
View file @
76714a5c
...
...
@@ -350,3 +350,7 @@ CREATE TABLE decode (decode int);
DROP TABLE decode;
CREATE TABLE rowcount (rowcount int);
DROP TABLE rowcount;
CREATE TABLE isopen (isopen int);
DROP TABLE isopen;
CREATE TABLE notfound (notfound int);
DROP TABLE notfound;
This diff is collapsed.
Click to expand it.
mysql-test/suite/compat/oracle/r/sp-cursor.result
0 → 100644
View file @
76714a5c
SET sql_mode=ORACLE;
#
# MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND
#
#
# Cursor attributes outside of an SP context
#
SELECT c%ISOPEN;
ERROR 42000: Undefined CURSOR: c
SELECT c%FOUND;
ERROR 42000: Undefined CURSOR: c
SELECT c%NOTFOUND;
ERROR 42000: Undefined CURSOR: c
SELECT c%ROWCOUNT;
ERROR 42000: Undefined CURSOR: c
#
# Undefinite cursor attributes
#
CREATE PROCEDURE p1
AS
BEGIN
SELECT c%ISOPEN;
END;
$$
ERROR 42000: Undefined CURSOR: c
CREATE PROCEDURE p1
AS
BEGIN
SELECT c%ROWCOUNT;
END;
$$
ERROR 42000: Undefined CURSOR: c
CREATE PROCEDURE p1
AS
BEGIN
SELECT c%FOUND;
END;
$$
ERROR 42000: Undefined CURSOR: c
CREATE PROCEDURE p1
AS
BEGIN
SELECT c%NOTFOUND;
END;
$$
ERROR 42000: Undefined CURSOR: c
#
# Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT
#
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT 1 AS c FROM DUAL;
BEGIN
SELECT c%ROWCOUNT;
END;
$$
CALL p1;
ERROR 24000: Cursor is not open
DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT 1 AS c FROM DUAL;
BEGIN
SELECT c%FOUND;
END;
$$
CALL p1;
ERROR 24000: Cursor is not open
DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT 1 AS c FROM DUAL;
BEGIN
SELECT c%NOTFOUND;
END;
$$
CALL p1;
ERROR 24000: Cursor is not open
DROP PROCEDURE p1;
#
# Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT with INVALID_CURSOR exception
#
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT 1 AS c FROM DUAL;
BEGIN
SELECT c%ROWCOUNT;
EXCEPTION
WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg;
END;
$$
CALL p1;
c%ROWCOUNT
msg
INVALID_CURSOR caught
DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT 1 AS c FROM DUAL;
BEGIN
SELECT c%FOUND;
EXCEPTION
WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg;
END;
$$
CALL p1;
c%FOUND
msg
INVALID_CURSOR caught
DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT 1 AS c FROM DUAL;
BEGIN
SELECT c%NOTFOUND;
EXCEPTION
WHEN INVALID_CURSOR THEN SELECT 'INVALID_CURSOR caught' AS msg;
END;
$$
CALL p1;
c%NOTFOUND
msg
INVALID_CURSOR caught
DROP PROCEDURE p1;
#
# print()
#
CREATE TABLE t1 (a INT);
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT * FROM t1 ORDER BY a;
BEGIN
EXPLAIN EXTENDED SELECT c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
END;
$$
CALL p1();
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 "c"%ISOPEN AS "c%ISOPEN","c"%ROWCOUNT AS "c%ROWCOUNT","c"%FOUND AS "c%FOUND","c"%NOTFOUND AS "c%NOTFOUND"
DROP PROCEDURE p1;
DROP TABLE t1;
#
# Declared data type of the attributes
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
CREATE PROCEDURE p1
AS
CURSOR c IS SELECT * FROM t1 ORDER BY a;
BEGIN
OPEN c;
CREATE TABLE t2 AS SELECT c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
SHOW CREATE TABLE t2;
DROP TABLE t2;
CLOSE c;
END;
$$
CALL p1();
Table Create Table
t2 CREATE TABLE "t2" (
"c%ISOPEN" int(1) NOT NULL,
"c%ROWCOUNT" bigint(21) NOT NULL,
"c%FOUND" int(1) DEFAULT NULL,
"c%NOTFOUND" int(1) DEFAULT NULL
)
DROP PROCEDURE p1;
DROP TABLE t1;
#
# Core functionality
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
INSERT INTO t1 VALUES (30);
CREATE PROCEDURE p1
AS
a INT:=0;
CURSOR c IS SELECT * FROM t1 ORDER BY a;
BEGIN
SELECT a, c%ISOPEN;
OPEN c;
/*
After OPEN and before FETCH:
- %ROWCOUNT returns 0
- %FOUND and %NOTFOUND return NULL
*/
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
FETCH c INTO a;
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
FETCH c INTO a;
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
FETCH c INTO a;
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
FETCH c INTO a;
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
CLOSE c;
SELECT a, c%ISOPEN;
/*
After reopen and before FETCH:
- %ROWCOUNT returns 0
- %FOUND and %NOTFOUND return NULL
*/
OPEN c;
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
FETCH c INTO a;
SELECT a, c%ISOPEN, c%ROWCOUNT, c%FOUND, c%NOTFOUND;
CLOSE c;
END;
$$
CALL p1();
a c%ISOPEN
0 0
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
0 1 0 NULL NULL
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
10 1 1 1 0
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
20 1 2 1 0
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
30 1 3 1 0
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
30 1 3 0 1
a c%ISOPEN
30 0
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
30 1 0 NULL NULL
a c%ISOPEN c%ROWCOUNT c%FOUND c%NOTFOUND
10 1 1 1 0
DROP PROCEDURE p1;
DROP TABLE t1;
#
# %NOTFOUND as a loop exit condition
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
INSERT INTO t1 VALUES (30);
CREATE PROCEDURE p1
AS
a INT:=0;
CURSOR c IS SELECT * FROM t1 ORDER BY a;
BEGIN
OPEN c;
LOOP
FETCH c INTO a;
EXIT WHEN c%NOTFOUND;
SELECT a;
END LOOP;
CLOSE c;
END;
$$
CALL p1();
a
10
a
20
a
30
DROP PROCEDURE p1;
DROP TABLE t1;
#
# %FOUND as a loop exit condition
#
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (10);
INSERT INTO t1 VALUES (20);
INSERT INTO t1 VALUES (30);
CREATE PROCEDURE p1
AS
a INT:=0;
CURSOR c IS SELECT * FROM t1 ORDER BY a;
BEGIN
OPEN c;
LOOP
FETCH c INTO a;
EXIT WHEN NOT c%FOUND;
SELECT a;
END LOOP;
CLOSE c;
END;
$$
CALL p1();
a
10
a
20
a
30
DROP PROCEDURE p1;
DROP TABLE t1;
This diff is collapsed.
Click to expand it.
mysql-test/suite/compat/oracle/t/sp-cursor.test
0 → 100644
View file @
76714a5c
SET
sql_mode
=
ORACLE
;
--
echo
#
--
echo
# MDEV-10582 sql_mode=ORACLE: explicit cursor attributes %ISOPEN, %ROWCOUNT, %FOUND, %NOTFOUND
--
echo
#
--
echo
#
--
echo
# Cursor attributes outside of an SP context
--
echo
#
--
error
ER_SP_CURSOR_MISMATCH
SELECT
c
%
ISOPEN
;
--
error
ER_SP_CURSOR_MISMATCH
SELECT
c
%
FOUND
;
--
error
ER_SP_CURSOR_MISMATCH
SELECT
c
%
NOTFOUND
;
--
error
ER_SP_CURSOR_MISMATCH
SELECT
c
%
ROWCOUNT
;
--
echo
#
--
echo
# Undefinite cursor attributes
--
echo
#
DELIMITER
$$
;
--
error
ER_SP_CURSOR_MISMATCH
CREATE
PROCEDURE
p1
AS
BEGIN
SELECT
c
%
ISOPEN
;
END
;
$$
--
error
ER_SP_CURSOR_MISMATCH
CREATE
PROCEDURE
p1
AS
BEGIN
SELECT
c
%
ROWCOUNT
;
END
;
$$
--
error
ER_SP_CURSOR_MISMATCH
CREATE
PROCEDURE
p1
AS
BEGIN
SELECT
c
%
FOUND
;
END
;
$$
--
error
ER_SP_CURSOR_MISMATCH
CREATE
PROCEDURE
p1
AS
BEGIN
SELECT
c
%
NOTFOUND
;
END
;
$$
DELIMITER
;
$$
--
echo
#
--
echo
# Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT
--
echo
#
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
1
AS
c
FROM
DUAL
;
BEGIN
SELECT
c
%
ROWCOUNT
;
END
;
$$
DELIMITER
;
$$
--
error
ER_SP_CURSOR_NOT_OPEN
CALL
p1
;
DROP
PROCEDURE
p1
;
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
1
AS
c
FROM
DUAL
;
BEGIN
SELECT
c
%
FOUND
;
END
;
$$
DELIMITER
;
$$
--
error
ER_SP_CURSOR_NOT_OPEN
CALL
p1
;
DROP
PROCEDURE
p1
;
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
1
AS
c
FROM
DUAL
;
BEGIN
SELECT
c
%
NOTFOUND
;
END
;
$$
DELIMITER
;
$$
--
error
ER_SP_CURSOR_NOT_OPEN
CALL
p1
;
DROP
PROCEDURE
p1
;
--
echo
#
--
echo
# Not opened cursor attributes %FOUND, %NOTFOUND, %ROWCOUNT with INVALID_CURSOR exception
--
echo
#
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
1
AS
c
FROM
DUAL
;
BEGIN
SELECT
c
%
ROWCOUNT
;
EXCEPTION
WHEN
INVALID_CURSOR
THEN
SELECT
'INVALID_CURSOR caught'
AS
msg
;
END
;
$$
DELIMITER
;
$$
CALL
p1
;
DROP
PROCEDURE
p1
;
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
1
AS
c
FROM
DUAL
;
BEGIN
SELECT
c
%
FOUND
;
EXCEPTION
WHEN
INVALID_CURSOR
THEN
SELECT
'INVALID_CURSOR caught'
AS
msg
;
END
;
$$
DELIMITER
;
$$
CALL
p1
;
DROP
PROCEDURE
p1
;
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
1
AS
c
FROM
DUAL
;
BEGIN
SELECT
c
%
NOTFOUND
;
EXCEPTION
WHEN
INVALID_CURSOR
THEN
SELECT
'INVALID_CURSOR caught'
AS
msg
;
END
;
$$
DELIMITER
;
$$
CALL
p1
;
DROP
PROCEDURE
p1
;
--
echo
#
--
echo
# print()
--
echo
#
CREATE
TABLE
t1
(
a
INT
);
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
*
FROM
t1
ORDER
BY
a
;
BEGIN
EXPLAIN
EXTENDED
SELECT
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
END
;
$$
DELIMITER
;
$$
CALL
p1
();
DROP
PROCEDURE
p1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Declared data type of the attributes
--
echo
#
CREATE
TABLE
t1
(
a
INT
);
INSERT
INTO
t1
VALUES
(
10
);
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
CURSOR
c
IS
SELECT
*
FROM
t1
ORDER
BY
a
;
BEGIN
OPEN
c
;
CREATE
TABLE
t2
AS
SELECT
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
SHOW
CREATE
TABLE
t2
;
DROP
TABLE
t2
;
CLOSE
c
;
END
;
$$
DELIMITER
;
$$
CALL
p1
();
DROP
PROCEDURE
p1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Core functionality
--
echo
#
CREATE
TABLE
t1
(
a
INT
);
INSERT
INTO
t1
VALUES
(
10
);
INSERT
INTO
t1
VALUES
(
20
);
INSERT
INTO
t1
VALUES
(
30
);
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
a
INT
:=
0
;
CURSOR
c
IS
SELECT
*
FROM
t1
ORDER
BY
a
;
BEGIN
SELECT
a
,
c
%
ISOPEN
;
OPEN
c
;
/*
After OPEN and before FETCH:
- %ROWCOUNT returns 0
- %FOUND and %NOTFOUND return NULL
*/
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
FETCH
c
INTO
a
;
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
FETCH
c
INTO
a
;
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
FETCH
c
INTO
a
;
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
FETCH
c
INTO
a
;
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
CLOSE
c
;
SELECT
a
,
c
%
ISOPEN
;
/*
After reopen and before FETCH:
- %ROWCOUNT returns 0
- %FOUND and %NOTFOUND return NULL
*/
OPEN
c
;
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
FETCH
c
INTO
a
;
SELECT
a
,
c
%
ISOPEN
,
c
%
ROWCOUNT
,
c
%
FOUND
,
c
%
NOTFOUND
;
CLOSE
c
;
END
;
$$
DELIMITER
;
$$
CALL
p1
();
DROP
PROCEDURE
p1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# %NOTFOUND as a loop exit condition
--
echo
#
CREATE
TABLE
t1
(
a
INT
);
INSERT
INTO
t1
VALUES
(
10
);
INSERT
INTO
t1
VALUES
(
20
);
INSERT
INTO
t1
VALUES
(
30
);
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
a
INT
:=
0
;
CURSOR
c
IS
SELECT
*
FROM
t1
ORDER
BY
a
;
BEGIN
OPEN
c
;
LOOP
FETCH
c
INTO
a
;
EXIT
WHEN
c
%
NOTFOUND
;
SELECT
a
;
END
LOOP
;
CLOSE
c
;
END
;
$$
DELIMITER
;
$$
CALL
p1
();
DROP
PROCEDURE
p1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# %FOUND as a loop exit condition
--
echo
#
CREATE
TABLE
t1
(
a
INT
);
INSERT
INTO
t1
VALUES
(
10
);
INSERT
INTO
t1
VALUES
(
20
);
INSERT
INTO
t1
VALUES
(
30
);
DELIMITER
$$
;
CREATE
PROCEDURE
p1
AS
a
INT
:=
0
;
CURSOR
c
IS
SELECT
*
FROM
t1
ORDER
BY
a
;
BEGIN
OPEN
c
;
LOOP
FETCH
c
INTO
a
;
EXIT
WHEN
NOT
c
%
FOUND
;
SELECT
a
;
END
LOOP
;
CLOSE
c
;
END
;
$$
DELIMITER
;
$$
CALL
p1
();
DROP
PROCEDURE
p1
;
DROP
TABLE
t1
;
This diff is collapsed.
Click to expand it.
mysql-test/t/keywords.test
View file @
76714a5c
...
...
@@ -247,3 +247,9 @@ DROP TABLE decode;
CREATE
TABLE
rowcount
(
rowcount
int
);
DROP
TABLE
rowcount
;
CREATE
TABLE
isopen
(
isopen
int
);
DROP
TABLE
isopen
;
CREATE
TABLE
notfound
(
notfound
int
);
DROP
TABLE
notfound
;
This diff is collapsed.
Click to expand it.
sql/item_func.cc
View file @
76714a5c
...
...
@@ -6862,4 +6862,52 @@ void Item_func_last_value::fix_length_and_dec()
}
void
Item_func_cursor_int_attr
::
print
(
String
*
str
,
enum_query_type
query_type
)
{
append_identifier
(
current_thd
,
str
,
m_cursor_name
.
str
,
m_cursor_name
.
length
);
str
->
append
(
func_name
());
}
sp_cursor
*
Item_func_cursor_int_attr
::
get_open_cursor_or_error
()
{
THD
*
thd
=
current_thd
;
sp_cursor
*
c
=
thd
->
spcont
->
get_cursor
(
m_cursor_offset
);
DBUG_ASSERT
(
c
);
if
(
!
c
/*safety*/
||
!
c
->
is_open
())
{
my_message
(
ER_SP_CURSOR_NOT_OPEN
,
ER_THD
(
thd
,
ER_SP_CURSOR_NOT_OPEN
),
MYF
(
0
));
return
NULL
;
}
return
c
;
}
longlong
Item_func_cursor_isopen
::
val_int
()
{
sp_cursor
*
c
=
current_thd
->
spcont
->
get_cursor
(
m_cursor_offset
);
DBUG_ASSERT
(
c
!=
NULL
);
return
c
?
c
->
is_open
()
:
0
;
}
longlong
Item_func_cursor_found
::
val_int
()
{
sp_cursor
*
c
=
get_open_cursor_or_error
();
return
!
(
null_value
=
(
!
c
||
c
->
fetch_count
()
==
0
))
&&
c
->
found
();
}
longlong
Item_func_cursor_notfound
::
val_int
()
{
sp_cursor
*
c
=
get_open_cursor_or_error
();
return
!
(
null_value
=
(
!
c
||
c
->
fetch_count
()
==
0
))
&&
!
c
->
found
();
}
longlong
Item_func_cursor_rowcount
::
val_int
()
{
sp_cursor
*
c
=
get_open_cursor_or_error
();
return
!
(
null_value
=
!
c
)
?
c
->
row_count
()
:
0
;
}
This diff is collapsed.
Click to expand it.
sql/item_func.h
View file @
76714a5c
...
...
@@ -725,6 +725,76 @@ class Item_int_func :public Item_func
};
class
Item_func_cursor_int_attr
:
public
Item_int_func
{
protected:
LEX_STRING
m_cursor_name
;
uint
m_cursor_offset
;
class
sp_cursor
*
get_open_cursor_or_error
();
public:
Item_func_cursor_int_attr
(
THD
*
thd
,
const
LEX_STRING
name
,
uint
offset
)
:
Item_int_func
(
thd
),
m_cursor_name
(
name
),
m_cursor_offset
(
offset
)
{
}
bool
check_vcol_func_processor
(
void
*
arg
)
{
return
mark_unsupported_function
(
func_name
(),
arg
,
VCOL_SESSION_FUNC
);
}
void
print
(
String
*
str
,
enum_query_type
query_type
);
};
class
Item_func_cursor_isopen
:
public
Item_func_cursor_int_attr
{
public:
Item_func_cursor_isopen
(
THD
*
thd
,
const
LEX_STRING
name
,
uint
offset
)
:
Item_func_cursor_int_attr
(
thd
,
name
,
offset
)
{
}
const
char
*
func_name
()
const
{
return
"%ISOPEN"
;
}
void
fix_length_and_dec
()
{
max_length
=
1
;
}
longlong
val_int
();
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_cursor_isopen
>
(
thd
,
mem_root
,
this
);
}
};
class
Item_func_cursor_found
:
public
Item_func_cursor_int_attr
{
public:
Item_func_cursor_found
(
THD
*
thd
,
const
LEX_STRING
name
,
uint
offset
)
:
Item_func_cursor_int_attr
(
thd
,
name
,
offset
)
{
}
const
char
*
func_name
()
const
{
return
"%FOUND"
;
}
void
fix_length_and_dec
()
{
max_length
=
1
;
maybe_null
=
true
;
}
longlong
val_int
();
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_cursor_found
>
(
thd
,
mem_root
,
this
);
}
};
class
Item_func_cursor_notfound
:
public
Item_func_cursor_int_attr
{
public:
Item_func_cursor_notfound
(
THD
*
thd
,
const
LEX_STRING
name
,
uint
offset
)
:
Item_func_cursor_int_attr
(
thd
,
name
,
offset
)
{
}
const
char
*
func_name
()
const
{
return
"%NOTFOUND"
;
}
void
fix_length_and_dec
()
{
max_length
=
1
;
maybe_null
=
true
;
}
longlong
val_int
();
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_cursor_notfound
>
(
thd
,
mem_root
,
this
);
}
};
class
Item_func_cursor_rowcount
:
public
Item_func_cursor_int_attr
{
public:
Item_func_cursor_rowcount
(
THD
*
thd
,
const
LEX_STRING
name
,
uint
offset
)
:
Item_func_cursor_int_attr
(
thd
,
name
,
offset
)
{
}
const
char
*
func_name
()
const
{
return
"%ROWCOUNT"
;
}
longlong
val_int
();
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_cursor_rowcount
>
(
thd
,
mem_root
,
this
);
}
};
class
Item_func_connection_id
:
public
Item_int_func
{
longlong
value
;
...
...
This diff is collapsed.
Click to expand it.
sql/lex.h
View file @
76714a5c
...
...
@@ -310,6 +310,7 @@ static SYMBOL symbols[] = {
{
"IPC"
,
SYM
(
IPC_SYM
)},
{
"IS"
,
SYM
(
IS
)},
{
"ISOLATION"
,
SYM
(
ISOLATION
)},
{
"ISOPEN"
,
SYM
(
ISOPEN_SYM
)},
{
"ISSUER"
,
SYM
(
ISSUER_SYM
)},
{
"ITERATE"
,
SYM
(
ITERATE_SYM
)},
{
"INVOKER"
,
SYM
(
INVOKER_SYM
)},
...
...
@@ -415,6 +416,7 @@ static SYMBOL symbols[] = {
{
"NODEGROUP"
,
SYM
(
NODEGROUP_SYM
)},
{
"NONE"
,
SYM
(
NONE_SYM
)},
{
"NOT"
,
SYM
(
NOT_SYM
)},
{
"NOTFOUND"
,
SYM
(
NOTFOUND_SYM
)},
{
"NO_WRITE_TO_BINLOG"
,
SYM
(
NO_WRITE_TO_BINLOG
)},
{
"NULL"
,
SYM
(
NULL_SYM
)},
{
"NUMBER"
,
SYM
(
NUMBER_SYM
)},
...
...
This diff is collapsed.
Click to expand it.
sql/sp_pcontext.cc
View file @
76714a5c
...
...
@@ -289,13 +289,15 @@ sp_condition_value *sp_pcontext::find_condition(const LEX_STRING name,
static
sp_condition_value
cond_invalid_cursor
(
ER_SP_CURSOR_NOT_OPEN
),
cond_no_data_found
(
ER_SP_FETCH_NO_DATA
),
cond_dup_val_on_index
(
ER_DUP_ENTRY
),
cond_too_many_rows
(
ER_TOO_MANY_ROWS
);
static
sp_condition
sp_predefined_conditions
[
3
]
=
static
sp_condition
sp_predefined_conditions
[]
=
{
sp_condition
(
C_STRING_WITH_LEN
(
"INVALID_CURSOR"
),
&
cond_invalid_cursor
),
sp_condition
(
C_STRING_WITH_LEN
(
"NO_DATA_FOUND"
),
&
cond_no_data_found
),
sp_condition
(
C_STRING_WITH_LEN
(
"DUP_VAL_ON_INDEX"
),
&
cond_dup_val_on_index
),
sp_condition
(
C_STRING_WITH_LEN
(
"TOO_MANY_ROWS"
),
&
cond_too_many_rows
)
...
...
This diff is collapsed.
Click to expand it.
sql/sp_rcontext.cc
View file @
76714a5c
...
...
@@ -425,7 +425,10 @@ sp_cursor::sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper, sp_instr_cpush *i)
result
(
thd_arg
),
m_lex_keeper
(
lex_keeper
),
server_side_cursor
(
NULL
),
m_i
(
i
)
m_i
(
i
),
m_fetch_count
(
0
),
m_row_count
(
0
),
m_found
(
false
)
{
/*
currsor can't be stored in QC, so we should prevent opening QC for
...
...
@@ -470,6 +473,8 @@ int sp_cursor::close(THD *thd)
MYF
(
0
));
return
-
1
;
}
m_row_count
=
m_fetch_count
=
0
;
m_found
=
false
;
destroy
();
return
0
;
}
...
...
@@ -497,6 +502,7 @@ int sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
return
-
1
;
}
m_fetch_count
++
;
DBUG_EXECUTE_IF
(
"bug23032_emit_warning"
,
push_warning
(
thd
,
Sql_condition
::
WARN_LEVEL_WARN
,
ER_UNKNOWN_ERROR
,
...
...
@@ -514,10 +520,15 @@ int sp_cursor::fetch(THD *thd, List<sp_variable> *vars)
*/
if
(
!
server_side_cursor
->
is_open
())
{
m_found
=
false
;
if
(
thd
->
variables
.
sql_mode
&
MODE_ORACLE
)
return
0
;
my_message
(
ER_SP_FETCH_NO_DATA
,
ER_THD
(
thd
,
ER_SP_FETCH_NO_DATA
),
MYF
(
0
));
return
-
1
;
}
m_found
=
true
;
m_row_count
++
;
return
0
;
}
...
...
This diff is collapsed.
Click to expand it.
sql/sp_rcontext.h
View file @
76714a5c
...
...
@@ -452,6 +452,15 @@ class sp_cursor : public Sql_alloc
my_bool
is_open
()
{
return
MY_TEST
(
server_side_cursor
);
}
bool
found
()
const
{
return
m_found
;
}
ulonglong
row_count
()
const
{
return
m_row_count
;
}
ulonglong
fetch_count
()
const
{
return
m_fetch_count
;
}
int
fetch
(
THD
*
,
List
<
sp_variable
>
*
vars
);
sp_instr_cpush
*
get_instr
()
...
...
@@ -461,7 +470,10 @@ class sp_cursor : public Sql_alloc
Select_fetch_into_spvars
result
;
sp_lex_keeper
*
m_lex_keeper
;
Server_side_cursor
*
server_side_cursor
;
sp_instr_cpush
*
m_i
;
// My push instruction
sp_instr_cpush
*
m_i
;
// My push instruction
ulonglong
m_fetch_count
;
// Number of FETCH commands since last OPEN
ulonglong
m_row_count
;
// Number of successful FETCH since last OPEN
bool
m_found
;
// If last FETCH fetched a row
void
destroy
();
};
// class sp_cursor : public Sql_alloc
...
...
This diff is collapsed.
Click to expand it.
sql/sql_yacc.yy
View file @
76714a5c
...
...
@@ -1181,6 +1181,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token IPC_SYM
%token IS /* SQL-2003-R */
%token ISOLATION /* SQL-2003-R */
%token ISOPEN_SYM /* Oracle-N */
%token ISSUER_SYM
%token ITERATE_SYM
%token JOIN_SYM /* SQL-2003-R */
...
...
@@ -1290,6 +1291,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NONE_SYM /* SQL-2003-R */
%token NOT2_SYM
%token NOT_SYM /* SQL-2003-R */
%token NOTFOUND_SYM /* Oracle-R */
%token NOW_SYM
%token NO_SYM /* SQL-2003-R */
%token NO_WAIT_SYM
...
...
@@ -14346,6 +14348,7 @@ keyword_sp:
| IO_SYM {}
| IPC_SYM {}
| ISOLATION {}
| ISOPEN_SYM {}
| ISSUER_SYM {}
| JSON_SYM {}
| INSERT_METHOD {}
...
...
@@ -14415,6 +14418,7 @@ keyword_sp:
| NO_WAIT_SYM {}
| NODEGROUP_SYM {}
| NONE_SYM {}
| NOTFOUND_SYM {}
| NUMBER_SYM {}
| NVARCHAR_SYM {}
| OFFSET_SYM {}
...
...
This diff is collapsed.
Click to expand it.
sql/sql_yacc_ora.yy
View file @
76714a5c
...
...
@@ -178,6 +178,11 @@ void ORAerror(THD *thd, const char *s)
Lex_field_type_st Lex_field_type;
Lex_dyncol_type_st Lex_dyncol_type;
Lex_for_loop_st for_loop;
struct
{
LEX_STRING name;
uint offset;
} sp_cursor_name_and_offset;
/* pointers */
Create_field *create_field;
...
...
@@ -555,6 +560,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token IPC_SYM
%token IS /* SQL-2003-R */
%token ISOLATION /* SQL-2003-R */
%token ISOPEN_SYM /* Oracle-N */
%token ISSUER_SYM
%token ITERATE_SYM
%token JOIN_SYM /* SQL-2003-R */
...
...
@@ -664,6 +670,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NONE_SYM /* SQL-2003-R */
%token NOT2_SYM
%token NOT_SYM /* SQL-2003-R */
%token NOTFOUND_SYM /* Oracle-R */
%token NOW_SYM
%token NO_SYM /* SQL-2003-R */
%token NO_WAIT_SYM
...
...
@@ -975,7 +982,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%left '&'
%left SHIFT_LEFT SHIFT_RIGHT
%left '-' '+'
%left '*' '/'
'%'
DIV_SYM MOD_SYM
%left '*' '/' DIV_SYM MOD_SYM
%left '^'
%left NEG '~'
%right NOT_SYM NOT2_SYM
...
...
@@ -1103,6 +1110,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
window_func_expr
window_func
simple_window_func
explicit_cursor_attr
function_call_keyword
function_call_nonkeyword
function_call_generic
...
...
@@ -1291,6 +1299,7 @@ END_OF_INPUT
%type <spblock> sp_decl_body sp_decl_body_list opt_sp_decl_body_list
%type <spblock_handlers> sp_block_statements_and_exceptions
%type <sp_instr_addr> sp_instr_addr
%type <sp_cursor_name_and_offset> sp_cursor_name_and_offset
%type <num> opt_exception_clause exception_handlers
%type <lex> sp_cursor_stmt
%type <spname> sp_name
...
...
@@ -8598,12 +8607,6 @@ bit_expr:
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr '%' bit_expr %prec '%'
{
$$= new (thd->mem_root) Item_func_mod(thd, $1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
| bit_expr DIV_SYM bit_expr %prec DIV_SYM
{
$$= new (thd->mem_root) Item_func_int_div(thd, $1, $3);
...
...
@@ -8740,6 +8743,44 @@ dyncall_create_list:
}
;
sp_cursor_name_and_offset:
ident
{
LEX *lex= Lex;
$$.name= $1;
if (!lex->spcont ||
!lex->spcont->find_cursor($1, &$$.offset, false))
my_yyabort_error((ER_SP_CURSOR_MISMATCH, MYF(0), $1.str));
}
;
explicit_cursor_attr:
sp_cursor_name_and_offset '%' ISOPEN_SYM
{
if (!($$= new (thd->mem_root)
Item_func_cursor_isopen(thd, $1.name, $1.offset)))
MYSQL_YYABORT;
}
| sp_cursor_name_and_offset '%' FOUND_SYM
{
if (!($$= new (thd->mem_root)
Item_func_cursor_found(thd, $1.name, $1.offset)))
MYSQL_YYABORT;
}
| sp_cursor_name_and_offset '%' NOTFOUND_SYM
{
if (!($$= new (thd->mem_root)
Item_func_cursor_notfound(thd, $1.name, $1.offset)))
MYSQL_YYABORT;
}
| sp_cursor_name_and_offset '%' ROWCOUNT_SYM
{
if (!($$= new (thd->mem_root)
Item_func_cursor_rowcount(thd, $1.name, $1.offset)))
MYSQL_YYABORT;
}
;
/*
Expressions that the parser allows in a column DEFAULT clause
without parentheses. These expressions cannot end with a COLLATE clause.
...
...
@@ -8904,6 +8945,7 @@ column_default_non_parenthesized_expr:
simple_expr:
column_default_non_parenthesized_expr
| explicit_cursor_attr
| simple_expr COLLATE_SYM ident_or_text %prec NEG
{
Item *i1= new (thd->mem_root) Item_string(thd, $3.str,
...
...
@@ -14306,6 +14348,7 @@ keyword_sp:
| IO_SYM {}
| IPC_SYM {}
| ISOLATION {}
| ISOPEN_SYM {}
| ISSUER_SYM {}
| JSON_SYM {}
| INSERT_METHOD {}
...
...
@@ -14375,6 +14418,7 @@ keyword_sp:
| NO_WAIT_SYM {}
| NODEGROUP_SYM {}
| NONE_SYM {}
| NOTFOUND_SYM {}
| NUMBER_SYM {}
| NVARCHAR_SYM {}
| OFFSET_SYM {}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment