!5974 增加嵌套数组插入表时报错处理
Merge pull request !5974 from chenxiaobin/fixNestTable
This commit is contained in:
@ -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);
|
||||
|
||||
/*
|
||||
|
@ -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. ")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user