PL/SQL parser - Phase 2 (MDEV-10764)

[MDEV-12307] ROW data type for built-in function return values Created: 2017-03-20  Updated: 2023-12-22

Status: Stalled
Project: MariaDB Server
Component/s: Data types
Affects Version/s: None
Fix Version/s: 11.5

Type: Technical task Priority: Major
Reporter: Alexander Barkov Assignee: Alexander Barkov
Resolution: Unresolved Votes: 1
Labels: Compatibility

Issue Links:
Blocks
blocks MDEV-12308 Accessing ROW type function fields Open
is blocked by MDEV-4912 Data type plugin API version 1 Closed
Relates
relates to MDEV-12252 ROW data type for stored function ret... In Review

 Description   

This task is related to MDEV-12252.

Under terms of this task we'll make it possible to return ROW data values from built-in hybrid functions:

  • IF
  • CASE

Other hybrid functions (COALESCE, IFNULL, NULLIF, LEAST, GREATEST) are out of scope of this task, because they involve NULL tests or comparison, which are not well defined for the ROW data type.

This SQL script:

SET sql_mode=DEFAULT;
DROP PROCEDURE p1;
DELIMITER $$
CREATE PROCEDURE p1()
BEGIN
  DECLARE rec0 ROW (a INT, b VARCHAR(10)) DEFAULT ROW(12,'b2');
  DECLARE rec1 ROW (a INT, b VARCHAR(10)) DEFAULT ROW(10,'b0');
  DECLARE rec2 ROW (a INT, b VARCHAR(10)) DEFAULT ROW(11,'b1');
  rec0 := CASE WHEN TRUE THEN rec1 ELSE rec2 END;
  SELECT rec0.a, rec0.b;
  rec0 := CASE WHEN FALSE THEN rec1 ELSE rec2 END;
  SELECT rec0.a, rec0.b;
END;
$$
DELIMITER ;
CALL p1();

will return

+--------+--------+
| rec0.a | rec0.b |
+--------+--------+
|     10 | b0     |
+--------+--------+
+--------+--------+
| rec0.a | rec0.b |
+--------+--------+
|     12 | b2     |
+--------+--------+

So will this script:

SET sql_mode=ORACLE;
DROP PROCEDURE p1;
DELIMITER $$
CREATE PROCEDURE p1
AS
  rec0 ROW (a INT, b VARCHAR(10)) := ROW(12,'b2');
  rec1 ROW (a INT, b VARCHAR(10)) := ROW(10,'b0');
  rec2 ROW (a INT, b VARCHAR(10)) := ROW(11,'b1');
BEGIN
  rec0 := CASE WHEN TRUE THEN rec1 ELSE rec2 END;
  SELECT rec0.a, rec0.b;
  rec0 := CASE WHEN FALSE THEN rec1 ELSE rec2 END;
  SELECT rec0.a, rec0.b;
END;
$$
DELIMITER ;
CALL p1();

An equivalent script in Oracle looks like:

SET SERVEROUTPUT ON;
DROP PROCEDURE p1;
CREATE PROCEDURE p1
AS
  TYPE rec_t IS RECORD (a INT := 10, b VARCHAR(10) :='b0');
  rec0 rec_t;
  rec1 rec_t;
  rec2 rec_t;
BEGIN
  rec2.a:= 12;
  rec2.b:= 'b2';
  rec0 := CASE WHEN TRUE THEN rec1 ELSE rec2 END;
  DBMS_OUTPUT.PUT_LINE(rec0.a || ' ' || rec0.b);
  rec0 := CASE WHEN FALSE THEN rec1 ELSE rec2 END;
  DBMS_OUTPUT.PUT_LINE(rec0.a || ' ' || rec0.b);
END;
/
CALL p1();


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