支持array和record嵌套
This commit is contained in:
@ -1508,14 +1508,20 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no
|
||||
|
||||
| K_TYPE decl_varname as_is K_VARRAY '(' ICONST ')' K_OF varray_var ';'
|
||||
{
|
||||
ereport(errstate,
|
||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmodule(MOD_PLSQL),
|
||||
errmsg("array type nested by array is not supported yet."),
|
||||
errdetail("Define array type \"%s\" of array is not supported yet.", $2->name),
|
||||
errcause("feature not supported"),
|
||||
erraction("check define of array type")));
|
||||
u_sess->plsql_cxt.have_error = true;
|
||||
IsInPublicNamespace($2->name);
|
||||
PLpgSQL_var *check_var = (PLpgSQL_var *)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$9];
|
||||
/* get and check nest tableof's depth */
|
||||
int depth = get_nest_tableof_layer(check_var, $2->name, errstate);
|
||||
PLpgSQL_type *nest_type = plpgsql_build_nested_datatype();
|
||||
nest_type->tableOfIndexType = INT4OID;
|
||||
nest_type->collectionType = PLPGSQL_COLLECTION_ARRAY;
|
||||
PLpgSQL_var* var = (PLpgSQL_var*)plpgsql_build_varrayType($2->name, $2->lineno, nest_type, true);
|
||||
/* nested table type */
|
||||
var->nest_table = (PLpgSQL_var *)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$9];
|
||||
var->nest_layers = depth;
|
||||
var->isIndexByTblOf = false;
|
||||
pfree_ext($2->name);
|
||||
pfree($2);
|
||||
}
|
||||
|
||||
| K_TYPE decl_varname as_is K_VARRAY '(' ICONST ')' K_OF table_var ';'
|
||||
@ -1552,6 +1558,8 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no
|
||||
IsInPublicNamespace(varname->name);
|
||||
|
||||
PLpgSQL_type *var_type = ((PLpgSQL_var *)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$3])->datatype;
|
||||
PLpgSQL_var *varray_type = (PLpgSQL_var *)u_sess->plsql_cxt.curr_compile_context->plpgsql_Datums[$3];
|
||||
|
||||
PLpgSQL_var *newp;
|
||||
PLpgSQL_type *new_var_type;
|
||||
|
||||
@ -1571,6 +1579,10 @@ decl_statement : decl_varname_list decl_const decl_datatype decl_collate decl_no
|
||||
errmsg("build variable failed")));
|
||||
u_sess->plsql_cxt.have_error = true;
|
||||
}
|
||||
if (varray_type->nest_table != NULL) {
|
||||
newp->nest_table = plpgsql_build_nested_variable(varray_type->nest_table, $2, varname->name, varname->lineno);
|
||||
newp->nest_layers = varray_type->nest_layers;
|
||||
}
|
||||
pfree_ext(varname->name);
|
||||
}
|
||||
list_free_deep($1);
|
||||
|
||||
@ -10506,7 +10506,8 @@ static void evalSubscriptList(PLpgSQL_execstate* estate, const List* subscripts,
|
||||
estate->eval_tuptable = NULL;
|
||||
|
||||
if (*target != NULL && (*target)->dtype == PLPGSQL_DTYPE_VAR &&
|
||||
((PLpgSQL_var*)(*target))->datatype->collectionType == PLPGSQL_COLLECTION_TABLE) {
|
||||
(((PLpgSQL_var*)(*target))->datatype->collectionType == PLPGSQL_COLLECTION_TABLE ||
|
||||
((PLpgSQL_var*)(*target))->datatype->collectionType == PLPGSQL_COLLECTION_ARRAY)) {
|
||||
int tableof_level = 0;
|
||||
char* valname = ((PLpgSQL_var*)(*target))->refname;
|
||||
PLpgSQL_expr* subexprs[nsubscripts];
|
||||
|
||||
@ -124,7 +124,7 @@ end;
|
||||
ERROR: mismatched parentheses at or near ";"
|
||||
LINE 12: insert into tmp values (null, name_list(1]);
|
||||
^
|
||||
QUERY: DECLARE cursor c_customers is (select c_name from customers order by id);
|
||||
QUERY: DECLARE cursor c_customers is (select c_name from customers order by id);
|
||||
type c_list is varray(6) of customers.c_name%type;
|
||||
name_list c_list := c_list();
|
||||
counter integer := 0;
|
||||
@ -302,7 +302,7 @@ end;
|
||||
ERROR: mismatched parentheses at or near ";"
|
||||
LINE 6: insert into tmp values (null, names(i]);
|
||||
^
|
||||
QUERY: DECLARE type students is varray(5) of varchar2(10);
|
||||
QUERY: DECLARE type students is varray(5) of varchar2(10);
|
||||
names students;
|
||||
begin
|
||||
names := students(1, 'Zera ', 'Alice', 'Jim ', 'Kevin'); -- should be able read all values correctly --
|
||||
@ -498,9 +498,12 @@ begin
|
||||
insert into tmp values (null, mat(1)(2));
|
||||
end;
|
||||
/
|
||||
ERROR: array type nested by array is not supported yet.
|
||||
DETAIL: Define array type "arraysecond" of array is not supported yet.
|
||||
CONTEXT: compilation of PL/pgSQL function "inline_code_block" near line 3
|
||||
ERROR: cannot cast type integer[] to integer
|
||||
LINE 1: SELECT ARRAY[(arr)::pg_catalog."int4", (arr)::pg_catalog."in...
|
||||
^
|
||||
QUERY: SELECT ARRAY[(arr)::pg_catalog."int4", (arr)::pg_catalog."int4"]
|
||||
CONTEXT: referenced column: array
|
||||
PL/pgSQL function inline_code_block line 5 during statement block local variable initialization
|
||||
select * from tmp order by 1, 2;
|
||||
a | b
|
||||
---+---
|
||||
|
||||
@ -0,0 +1,90 @@
|
||||
-- check compatibility --
|
||||
show sql_compatibility; -- expect A --
|
||||
sql_compatibility
|
||||
-------------------
|
||||
A
|
||||
(1 row)
|
||||
|
||||
DROP SCHEMA IF EXISTS plpgsql_nested_array_and_record CASCADE;
|
||||
NOTICE: schema "plpgsql_nested_array_and_record" does not exist, skipping
|
||||
CREATE SCHEMA plpgsql_nested_array_and_record;
|
||||
SET current_schema = plpgsql_nested_array_and_record;
|
||||
-- array of arrays
|
||||
DECLARE
|
||||
TYPE arr1 IS VARRAY(5) OF INTEGER;
|
||||
TYPE arr2 IS VARRAY(5) OF arr1;
|
||||
nst_arr arr2;
|
||||
BEGIN
|
||||
FOR I IN 1..5 LOOP
|
||||
nst_arr(1)(I) := I;
|
||||
RAISE NOTICE 'RESULT: %', nst_arr(1)(I);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
NOTICE: RESULT: 1
|
||||
NOTICE: RESULT: 2
|
||||
NOTICE: RESULT: 3
|
||||
NOTICE: RESULT: 4
|
||||
NOTICE: RESULT: 5
|
||||
-- record of arrays
|
||||
DECLARE
|
||||
TYPE arr1 IS VARRAY(5) OF INTEGER;
|
||||
TYPE rec1 IS RECORD(id int, arrarg arr1);
|
||||
arr_rec rec1;
|
||||
BEGIN
|
||||
FOR I IN 1..5 LOOP
|
||||
arr_rec.arrarg(I):=I;
|
||||
RAISE NOTICE 'RESULT: %', arr_rec.arrarg(I);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
NOTICE: RESULT: 1
|
||||
NOTICE: RESULT: 2
|
||||
NOTICE: RESULT: 3
|
||||
NOTICE: RESULT: 4
|
||||
NOTICE: RESULT: 5
|
||||
-- array of records
|
||||
CREATE OR REPLACE PROCEDURE test_nested AS
|
||||
DECLARE
|
||||
TYPE rec1 IS RECORD(id int, name char(10));
|
||||
TYPE arr1 IS VARRAY(5) OF rec1;
|
||||
rec_arr arr1;
|
||||
BEGIN
|
||||
FOR I IN 1..5 LOOP
|
||||
rec_arr(I).id := I;
|
||||
RAISE NOTICE 'RESULT: %', rec_arr(I).id;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
CALL test_nested();
|
||||
NOTICE: RESULT: 1
|
||||
NOTICE: RESULT: 2
|
||||
NOTICE: RESULT: 3
|
||||
NOTICE: RESULT: 4
|
||||
NOTICE: RESULT: 5
|
||||
test_nested
|
||||
-------------
|
||||
|
||||
(1 row)
|
||||
|
||||
-- record of records
|
||||
CREATE OR REPLACE PROCEDURE test_nested AS
|
||||
DECLARE
|
||||
TYPE rec1 IS RECORD(id int, name char(10));
|
||||
TYPE rec2 IS RECORD(id int, recarg rec1);
|
||||
recrec rec2;
|
||||
BEGIN
|
||||
recrec.recarg.id := 1;
|
||||
recrec.recarg.name := 'RECORD';
|
||||
RAISE NOTICE 'ID: %, NAME: %', recrec.recarg.id, recrec.recarg.name;
|
||||
END;
|
||||
/
|
||||
CALL test_nested();
|
||||
NOTICE: ID: 1, NAME: RECORD
|
||||
test_nested
|
||||
-------------
|
||||
|
||||
(1 row)
|
||||
|
||||
DROP SCHEMA plpgsql_nested_array_and_record CASCADE;
|
||||
NOTICE: drop cascades to function test_nested()
|
||||
@ -434,9 +434,6 @@ type t1 is varray(10) of int;
|
||||
type t2 is varray(10) of t1;
|
||||
end pck1;
|
||||
/
|
||||
ERROR: array type nested by array is not supported yet.
|
||||
DETAIL: Define array type "t2" of array is not supported yet.
|
||||
CONTEXT: compilation of PL/pgSQL package near line 3
|
||||
create or replace function func1() return int as
|
||||
type t1 is varray(10) of int;
|
||||
type t2 is varray(10) of t1;
|
||||
@ -444,9 +441,6 @@ begin
|
||||
return 0;
|
||||
end;
|
||||
/
|
||||
ERROR: array type nested by array is not supported yet.
|
||||
DETAIL: Define array type "t2" of array is not supported yet.
|
||||
CONTEXT: compilation of PL/pgSQL function "func1" near line 2
|
||||
-- 2. table nest array
|
||||
create or replace package pck1 as
|
||||
type t1 is varray(10) of int;
|
||||
@ -500,7 +494,6 @@ CONTEXT: compilation of PL/pgSQL function "func1" near line 2
|
||||
-- /
|
||||
-- 5. record nest ref cursor
|
||||
drop package if exists pck1;
|
||||
NOTICE: package pck1() does not exist, skipping
|
||||
create or replace package pck1 as
|
||||
type t1 is ref cursor;
|
||||
type t2 is record(c1 t1,c2 int);
|
||||
@ -560,7 +553,6 @@ CONTEXT: compilation of PL/pgSQL function "func1" near line 2
|
||||
DROP package pck1;
|
||||
ERROR: package pck1 does not exist
|
||||
DROP function func1();
|
||||
ERROR: function func1 does not exist
|
||||
-- 8.package nest
|
||||
create or replace package pck1 as
|
||||
type t1 is table of int;
|
||||
|
||||
@ -776,7 +776,7 @@ test: select_where_func
|
||||
test: arrayinterface_single
|
||||
test: plpgsql_table_opengauss
|
||||
test: plpgsql_assign_value_to_array_attribute
|
||||
test: plpgsql_array_of_record
|
||||
test: plpgsql_array_of_record
|
||||
#test: plpgsql_nest_compile
|
||||
test: arrayinterface_ted
|
||||
test: function_default_test plpgsql_inout_param record_slow_sql_in_proc
|
||||
@ -787,7 +787,7 @@ test: plpgsql_record_attrname
|
||||
test: plpgsql_insert_record plpgsql_condition_name
|
||||
test: hw_package_variable package_typmod_test
|
||||
test: autonomous_cursor
|
||||
test: plpgsql_reset_session
|
||||
test: plpgsql_reset_session plpgsql_nested_array_and_record
|
||||
#test: plpgsql_depend
|
||||
test: plpgsql_depend/plpgsql_depend_type plpgsql_depend/plpgsql_pkg_dependency plpgsql_depend/plpgsql_recompile plpgsql_depend/plpgsql_pkg_variable_dependency plpgsql_depend/plpgsql_depend_reftype
|
||||
#test: plancache limit rangefuncs prepare
|
||||
|
||||
@ -280,7 +280,7 @@ test: select_where_func
|
||||
test: arrayinterface_single
|
||||
test: plpgsql_table_opengauss
|
||||
test: plpgsql_assign_value_to_array_attribute
|
||||
test: plpgsql_array_of_record
|
||||
test: plpgsql_array_of_record
|
||||
#test: plpgsql_nest_compile
|
||||
test: arrayinterface_ted
|
||||
test: function_default_test plpgsql_inout_param
|
||||
@ -291,7 +291,7 @@ test: plpgsql_record_attrname
|
||||
test: plpgsql_insert_record plpgsql_condition_name
|
||||
test: hw_package_variable package_typmod_test
|
||||
test: autonomous_cursor
|
||||
test: plpgsql_reset_session
|
||||
test: plpgsql_reset_session plpgsql_nested_array_and_record
|
||||
#test: plpgsql_depend
|
||||
test: plpgsql_depend/plpgsql_depend_type plpgsql_depend/plpgsql_pkg_dependency plpgsql_depend/plpgsql_recompile plpgsql_depend/plpgsql_pkg_variable_dependency plpgsql_depend/plpgsql_depend_reftype
|
||||
#test: plancache limit rangefuncs prepare
|
||||
|
||||
63
src/test/regress/sql/plpgsql_nested_array_and_record.sql
Normal file
63
src/test/regress/sql/plpgsql_nested_array_and_record.sql
Normal file
@ -0,0 +1,63 @@
|
||||
-- check compatibility --
|
||||
show sql_compatibility; -- expect A --
|
||||
|
||||
DROP SCHEMA IF EXISTS plpgsql_nested_array_and_record CASCADE;
|
||||
CREATE SCHEMA plpgsql_nested_array_and_record;
|
||||
SET current_schema = plpgsql_nested_array_and_record;
|
||||
|
||||
-- array of arrays
|
||||
DECLARE
|
||||
TYPE arr1 IS VARRAY(5) OF INTEGER;
|
||||
TYPE arr2 IS VARRAY(5) OF arr1;
|
||||
nst_arr arr2;
|
||||
BEGIN
|
||||
FOR I IN 1..5 LOOP
|
||||
nst_arr(1)(I) := I;
|
||||
RAISE NOTICE 'RESULT: %', nst_arr(1)(I);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
-- record of arrays
|
||||
DECLARE
|
||||
TYPE arr1 IS VARRAY(5) OF INTEGER;
|
||||
TYPE rec1 IS RECORD(id int, arrarg arr1);
|
||||
arr_rec rec1;
|
||||
BEGIN
|
||||
FOR I IN 1..5 LOOP
|
||||
arr_rec.arrarg(I):=I;
|
||||
RAISE NOTICE 'RESULT: %', arr_rec.arrarg(I);
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
|
||||
-- array of records
|
||||
CREATE OR REPLACE PROCEDURE test_nested AS
|
||||
DECLARE
|
||||
TYPE rec1 IS RECORD(id int, name char(10));
|
||||
TYPE arr1 IS VARRAY(5) OF rec1;
|
||||
rec_arr arr1;
|
||||
BEGIN
|
||||
FOR I IN 1..5 LOOP
|
||||
rec_arr(I).id := I;
|
||||
RAISE NOTICE 'RESULT: %', rec_arr(I).id;
|
||||
END LOOP;
|
||||
END;
|
||||
/
|
||||
CALL test_nested();
|
||||
|
||||
-- record of records
|
||||
CREATE OR REPLACE PROCEDURE test_nested AS
|
||||
DECLARE
|
||||
TYPE rec1 IS RECORD(id int, name char(10));
|
||||
TYPE rec2 IS RECORD(id int, recarg rec1);
|
||||
recrec rec2;
|
||||
BEGIN
|
||||
recrec.recarg.id := 1;
|
||||
recrec.recarg.name := 'RECORD';
|
||||
RAISE NOTICE 'ID: %, NAME: %', recrec.recarg.id, recrec.recarg.name;
|
||||
END;
|
||||
/
|
||||
CALL test_nested();
|
||||
|
||||
DROP SCHEMA plpgsql_nested_array_and_record CASCADE;
|
||||
Reference in New Issue
Block a user