From 8b19fc797230a00395169b5165ff5e6dc5be1bea Mon Sep 17 00:00:00 2001 From: chenxiaobin19 <1025221611@qq.com> Date: Fri, 16 Dec 2022 15:04:20 +0800 Subject: [PATCH] fix not null constraint of record unaffective bug --- src/common/pl/plpgsql/src/pl_comp.cpp | 5 +++-- src/include/utils/plpgsql.h | 2 +- .../expected/plpgsql_record_attrname.out | 19 +++++++++++++++++++ .../regress/sql/plpgsql_record_attrname.sql | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/common/pl/plpgsql/src/pl_comp.cpp b/src/common/pl/plpgsql/src/pl_comp.cpp index 534c325ec2..492cc35441 100644 --- a/src/common/pl/plpgsql/src/pl_comp.cpp +++ b/src/common/pl/plpgsql/src/pl_comp.cpp @@ -3408,7 +3408,7 @@ void plpgsql_set_variable(const char* varname, int value) * array, and optionally to the current namespace. */ PLpgSQL_variable* plpgsql_build_variable(const char* refname, int lineno, PLpgSQL_type* dtype, bool add2namespace, - bool isImplicit, const char* varname, knl_pl_body_type plType) + bool isImplicit, const char* varname, knl_pl_body_type plType, bool notNull) { PLpgSQL_variable* result = NULL; int varno; @@ -3428,6 +3428,7 @@ PLpgSQL_variable* plpgsql_build_variable(const char* refname, int lineno, PLpgSQ var->refname = pstrdup(refname); var->lineno = lineno; var->datatype = dtype; + var->notnull = (int)notNull; var->pkg = NULL; var->customCondition = 0; /* other fields might be filled by caller */ @@ -3901,7 +3902,7 @@ PLpgSQL_row* build_row_from_rec_type(const char* rowname, int lineno, PLpgSQL_re rc = snprintf_s(buf, len, len - 1, "%s.%s", row->refname, type->attrnames[i]); securec_check_ss(rc, "", ""); - var = plpgsql_build_variable(buf, lineno, type->types[i], false); + var = plpgsql_build_variable(buf, lineno, type->types[i], false, false, NULL, PL_BODY_FUNCTION, type->notnulls[i]); if (type->defaultvalues[i] != NULL) ((PLpgSQL_var*)var)->default_val = type->defaultvalues[i]; diff --git a/src/include/utils/plpgsql.h b/src/include/utils/plpgsql.h index 7cc3f30b73..59db0470d4 100644 --- a/src/include/utils/plpgsql.h +++ b/src/include/utils/plpgsql.h @@ -1566,7 +1566,7 @@ extern const char *plpgsql_code_int2cstring(int sqlcode); extern const int plpgsql_code_cstring2int(const char *codename); extern void plpgsql_set_variable(const char* varname, int value); extern PLpgSQL_variable* plpgsql_build_variable(const char* refname, int lineno, PLpgSQL_type* dtype, bool add2namespace, bool isImplicit = false, - const char* varname = NULL, knl_pl_body_type plType = PL_BODY_FUNCTION); + const char* varname = NULL, knl_pl_body_type plType = PL_BODY_FUNCTION, bool notNull = false); PLpgSQL_variable* plpgsql_build_varrayType(const char* refname, int lineno, PLpgSQL_type* dtype, bool add2namespace); PLpgSQL_variable* plpgsql_build_tableType(const char* refname, int lineno, PLpgSQL_type* dtype, bool add2namespace); extern PLpgSQL_rec_type* plpgsql_build_rec_type(const char* typname, int lineno, List* list, bool add2namespace); diff --git a/src/test/regress/expected/plpgsql_record_attrname.out b/src/test/regress/expected/plpgsql_record_attrname.out index 28df3ce201..94b42388eb 100644 --- a/src/test/regress/expected/plpgsql_record_attrname.out +++ b/src/test/regress/expected/plpgsql_record_attrname.out @@ -94,6 +94,25 @@ CONTEXT: referenced column: f1 4 (1 row) +--test not null +CREATE OR REPLACE FUNCTION regress_record1(p_w VARCHAR2) +RETURNS +VARCHAR2 AS $$ +DECLARE +type rec_type is record (name varchar2(100) not null default 'a', epno int); +employer rec_type; +BEGIN +employer.name := null; +employer.epno = 18; +raise info 'employer name: % , epno:%', employer.name, employer.epno; +return employer.name; +END; +$$ +LANGUAGE plpgsql; +CALL regress_record1('aaa'); +ERROR: null value cannot be assigned to variable "employer.name" declared NOT NULL +CONTEXT: PL/pgSQL function regress_record1(character varying) line 6 at assignment +DROP FUNCTION regress_record1; -------------------------------------------------- ------------------ END OF TESTS ------------------ -------------------------------------------------- diff --git a/src/test/regress/sql/plpgsql_record_attrname.sql b/src/test/regress/sql/plpgsql_record_attrname.sql index 8fb134bd12..15058dfd82 100644 --- a/src/test/regress/sql/plpgsql_record_attrname.sql +++ b/src/test/regress/sql/plpgsql_record_attrname.sql @@ -80,6 +80,24 @@ end p_test2; select p_test2.f1((1,2,3,4,5,6)); +--test not null +CREATE OR REPLACE FUNCTION regress_record1(p_w VARCHAR2) +RETURNS +VARCHAR2 AS $$ +DECLARE +type rec_type is record (name varchar2(100) not null default 'a', epno int); +employer rec_type; +BEGIN +employer.name := null; +employer.epno = 18; +raise info 'employer name: % , epno:%', employer.name, employer.epno; +return employer.name; +END; +$$ +LANGUAGE plpgsql; +CALL regress_record1('aaa'); +DROP FUNCTION regress_record1; + -------------------------------------------------- ------------------ END OF TESTS ------------------ -------------------------------------------------- -- Gitee