PL/SQL parser (MDEV-10142)

[MDEV-10597] sql_mode=ORACLE: Cursors with parameters Created: 2016-08-19  Updated: 2020-08-27  Resolved: 2016-10-21

Status: Closed
Project: MariaDB Server
Component/s: Parser, Stored routines
Affects Version/s: None
Fix Version/s: 10.3.0

Type: Technical task Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Fixed Votes: 0
Labels: Compatibility

Issue Links:
Relates
relates to MDEV-12209 sql_mode=ORACLE: Syntax error in a OP... Closed
relates to MDEV-12441 Variables declared after cursors with... Closed
relates to MDEV-12457 Cursors with parameters Closed
Sprint: 10.2.2-3, 10.2.2-1, 10.2.2-2, 10.2.2-4, 10.1.18

 Description   

Add optional parameter list into CURSOR declaration and OPEN.

Example:

DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT, c INT);
INSERT INTO t1 VALUES (1,2,3);
DECLARE
  CURSOR c (prm_a VARCHAR2, prm_b VARCHAR2) IS
    SELECT a, b, c FROM t1 WHERE a=prm_a AND b=prm_b;
  v_a INT;
  v_b INT;
  v_c INT;
BEGIN
  OPEN c(1, 2);
  FETCH c INTO v_a, v_b, v_c;
  CLOSE c;
  INSERT INTO t1 VALUES (v_a + 10, v_b + 10, v_c + 10);
EXCEPTION
  WHEN NO_DATA_FOUND THEN RETURN;
END;
/
SELECT * FROM t1;
DROP TABLE t1;

	 A	    B	       C
---------- ---------- ----------
	 1	    2	       3
	11	   12	      13

Cursor parameter name space

Cursor parameters exists in a separate name space and shadow the variables declared on the same level with the cursor, or on upper levels. This script:

SET SERVEROUTPUT ON ;
DROP TABLE t1;
DROP PROCEDURE p1;
CREATE TABLE t1 (a INT);
INSERT INTO t1 VALUES (1);
CREATE PROCEDURE p1(a INT)
AS
  v_a INT:=NULL;
  p_a INT:=NULL;
  CURSOR c (p_a VARCHAR2) IS SELECT a FROM t1 WHERE p_a IS NOT NULL;
BEGIN
  OPEN c(a);
  FETCH c INTO v_a;
  IF c%NOTFOUND THEN
  BEGIN
    DBMS_OUTPUT.PUT_LINE('No records found');
    RETURN;
  END;
  END IF;
  CLOSE c;
  DBMS_OUTPUT.PUT_LINE('Fetched a record a='||TO_CHAR(v_a));
  INSERT INTO t1 VALUES (v_a);
  COMMIT;
END;
/
CALL p1(1);
SELECT * FROM t1;

returns

SQL> Fetched a record a=1

SQL> 
	 A
----------
	 1
	 1

Notice, the procedure call inserted the second record into the table t1, because the cursor parameter p_a shadowed the local variable p_a and the condition WHERE p_a IS NOT NULL evaluated to TRUE, because the cursor parameter p_a was initialized to 1 at OPEN c(a) time. The value of the local variable p_a is not important, as it's not visible in the cursor SELECT expression.


Generated at Thu Feb 08 07:43:26 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.