diff --git a/src/common/pl/plpgsql/src/pl_comp.cpp b/src/common/pl/plpgsql/src/pl_comp.cpp index 534c325ec218ea60dfb0e510b0d1ddaf5d5b3ac8..492cc354415814b44e26cf1206764f8f25bbafc8 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 7cc3f30b730b62f470fc0e6005783a3fb100cab4..59db0470d4246214d14bf47b7659e373739f1a2f 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 28df3ce201dbfcf1e81be030bb101f419a83a5c9..94b42388ebe7c028faf808c2ee79063ebedcbce4 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 8fb134bd123df5b54c83f06d7e29fe288df78a2b..15058dfd828c50de898297272273fdd3286546c1 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 ------------------ --------------------------------------------------