!5974 增加嵌套数组插入表时报错处理

Merge pull request !5974 from chenxiaobin/fixNestTable
This commit is contained in:
opengauss_bot
2024-08-08 12:28:48 +00:00
committed by Gitee
4 changed files with 207 additions and 1 deletions

View File

@ -54,6 +54,8 @@ static List* ExpandSingleTable(ParseState* pstate, RangeTblEntry* rte, int locat
static List* ExpandRowReference(ParseState* pstate, Node* expr, bool targetlist);
static int FigureColnameInternal(Node* node, char** name);
extern void checkArrayTypeInsert(ParseState* pstate, Expr* expr);
/*
* @Description: return the last filed's name and ignore * or subscrpts
* @in field: list of field to search
@ -443,6 +445,10 @@ Expr* transformAssignedExpr(ParseState* pstate, Expr* expr, ParseExprKind exprKi
type_id = exprType((Node*)expr);
type_mod = exprTypmod((Node*)expr);
if (IsA(expr, Param) || (IsA(expr, ArrayRef) && ((ArrayRef*)expr)->refexpr != NULL)) {
checkArrayTypeInsert(pstate, expr);
}
ELOG_FIELD_NAME_START(colname);
/*

View File

@ -5685,4 +5685,30 @@ Oid searchsubtypebytypeId(Oid typeOid, int32 *typmod)
errmsg("unsupported search subtype by type %u", typeOid)));
}
return type == TYPTYPE_TABLEOF ? searchsubtypebytypeId(resultType, typmod) : resultType;
}
}
void checkArrayTypeInsert(ParseState* pstate, Expr* expr)
{
Param* param = NULL;
if (IsA(expr, Param)) {
param = (Param*)expr;
} else if (IsA(expr, ArrayRef) && IsA(((ArrayRef*)expr)->refexpr, Param)) {
param = (Param*)((ArrayRef*)expr)->refexpr;
} else {
return;
}
if (pstate->p_pre_columnref_hook == plpgsql_pre_column_ref && pstate->p_ref_hook_state != NULL) {
PLpgSQL_expr* pl_expr = (PLpgSQL_expr*)pstate->p_ref_hook_state;
if (pl_expr->func != NULL && param->paramid <= pl_expr->func->ndatums &&
pl_expr->func->datums[param->paramid - 1]->dtype == PLPGSQL_DTYPE_VAR) {
PLpgSQL_var* var = (PLpgSQL_var*)pl_expr->func->datums[param->paramid - 1];
if (var->nest_table != NULL && (IsA(expr, Param) ||
var->nest_layers != list_length(((ArrayRef*)expr)->refupperindexpr))) {
ereport(ERROR, (errmsg("The tableof type variable cannot be used as an insertion value. ")));
}
}
}
}

View File

@ -926,6 +926,101 @@ INFO: plpgsql_table_opengauss.pck1.v2(2) is 3
0
(1 row)
create table t_PLArray_ (id int ,col varchar(500));
create or replace procedure p_PLArray_
as
type typ_PLArray_1 is table of varchar(50);
type typ_PLArray_2 is table of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
nstarr(1)(2):='第一行第二列';
insert into t_PLArray_(col) values (nstarr(1));
end;
/
call p_PLArray_();
ERROR: The tableof type variable cannot be used as an insertion value.
CONTEXT: SQL statement "insert into t_PLArray_(col) values (nstarr[1])"
PL/pgSQL function p_plarray_() line 8 at SQL statement
create or replace procedure p_PLArray_
as
type typ_PLArray_1 is table of varchar(50);
type typ_PLArray_2 is table of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
nstarr(1)(2):='第一行第二列';
insert into t_PLArray_(col) values (nstarr);
end;
/
call p_PLArray_();
ERROR: The tableof type variable cannot be used as an insertion value.
CONTEXT: SQL statement "insert into t_PLArray_(col) values (nstarr)"
PL/pgSQL function p_plarray_() line 8 at SQL statement
create or replace procedure p_PLArray_
as
type typ_PLArray_1 is table of varchar(50);
type typ_PLArray_2 is table of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
nstarr(1)(2):='第一行第二列';
insert into t_PLArray_(col) values (nstarr(1)(1));
insert into t_PLArray_(col) values (nstarr(1)(2));
end;
/
call p_PLArray_();
p_plarray_
------------
(1 row)
declare
type typ_PLArray_1 is varray(3) of varchar(50);
type typ_PLArray_2 is varray(3) of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
insert into t_PLArray_(col) values (nstarr(1));
end;
/
ERROR: The tableof type variable cannot be used as an insertion value.
CONTEXT: SQL statement "insert into t_PLArray_(col) values (nstarr[1])"
PL/pgSQL function inline_code_block line 6 at SQL statement
declare
type typ_PLArray_1 is varray(3) of varchar(50);
type typ_PLArray_2 is varray(3) of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
insert into t_PLArray_(col) values (nstarr);
end;
/
ERROR: The tableof type variable cannot be used as an insertion value.
CONTEXT: SQL statement "insert into t_PLArray_(col) values (nstarr)"
PL/pgSQL function inline_code_block line 6 at SQL statement
declare
type typ_PLArray_1 is varray(3) of varchar(50);
type typ_PLArray_2 is varray(3) of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
insert into t_PLArray_(col) values (nstarr(1)(1));
end;
/
select * from t_PLArray_;
id | col
----+--------------
| 第一行第一列
| 第一行第二列
| 第一行第一列
(3 rows)
drop table t_PLArray_;
drop procedure p_PLArray_;
-- test pg_get_function_result and pg_get_function_arguments
create type ty_test is(col1 int,col2 char(10),col3 varchar2(10));
create type tyt_test is table of ty_test;

View File

@ -769,6 +769,85 @@ end;
/
call func2();
create table t_PLArray_ (id int ,col varchar(500));
create or replace procedure p_PLArray_
as
type typ_PLArray_1 is table of varchar(50);
type typ_PLArray_2 is table of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
nstarr(1)(2):='第一行第二列';
insert into t_PLArray_(col) values (nstarr(1));
end;
/
call p_PLArray_();
create or replace procedure p_PLArray_
as
type typ_PLArray_1 is table of varchar(50);
type typ_PLArray_2 is table of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
nstarr(1)(2):='第一行第二列';
insert into t_PLArray_(col) values (nstarr);
end;
/
call p_PLArray_();
create or replace procedure p_PLArray_
as
type typ_PLArray_1 is table of varchar(50);
type typ_PLArray_2 is table of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
nstarr(1)(2):='第一行第二列';
insert into t_PLArray_(col) values (nstarr(1)(1));
insert into t_PLArray_(col) values (nstarr(1)(2));
end;
/
call p_PLArray_();
declare
type typ_PLArray_1 is varray(3) of varchar(50);
type typ_PLArray_2 is varray(3) of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
insert into t_PLArray_(col) values (nstarr(1));
end;
/
declare
type typ_PLArray_1 is varray(3) of varchar(50);
type typ_PLArray_2 is varray(3) of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
insert into t_PLArray_(col) values (nstarr);
end;
/
declare
type typ_PLArray_1 is varray(3) of varchar(50);
type typ_PLArray_2 is varray(3) of typ_PLArray_1;
nstarr typ_PLArray_2;
begin
nstarr(1)(1):='第一行第一列';
insert into t_PLArray_(col) values (nstarr(1)(1));
end;
/
select * from t_PLArray_;
drop table t_PLArray_;
drop procedure p_PLArray_;
-- test pg_get_function_result and pg_get_function_arguments
create type ty_test is(col1 int,col2 char(10),col3 varchar2(10));
create type tyt_test is table of ty_test;