diff --git a/src/common/backend/catalog/builtin_funcs.ini b/src/common/backend/catalog/builtin_funcs.ini index f119e3548f71c8d6fce3f2c50de7c559b19d6a03..d38a8940ca03b70bd360e74c81ca93940397c358 100644 --- a/src/common/backend/catalog/builtin_funcs.ini +++ b/src/common/backend/catalog/builtin_funcs.ini @@ -11008,6 +11008,18 @@ AddFuncGroup( "similar_escape", 1, AddBuiltinFunc(_0(1623), _1("similar_escape"), _2(2), _3(false), _4(false), _5(similar_escape), _6(25), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 25, 25), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("similar_escape"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("convert SQL regexp pattern to POSIX style"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) ), + AddFuncGroup( + "simple_integer_mul", 1, + AddBuiltinFunc(_0(3361), _1("simple_integer_mul"), _2(2), _3(false), _4(false), _5(simple_integer_mul), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("simple_integer_mul"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "simple_integer_plus", 1, + AddBuiltinFunc(_0(3362), _1("simple_integer_plus"), _2(2), _3(false), _4(false), _5(simple_integer_plus), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("simple_integer_plus"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), + AddFuncGroup( + "simple_integer_sub", 1, + AddBuiltinFunc(_0(3364), _1("simple_integer_sub"), _2(2), _3(false), _4(false), _5(simple_integer_sub), _6(23), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(2, 23, 23), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("simple_integer_sub"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(false), _32(false), _33(NULL), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) + ), AddFuncGroup( "sin", 1, AddBuiltinFunc(_0(SINEFUNCOID), _1("sin"), _2(1), _3(true), _4(false), _5(dsin), _6(701), _7(PG_CATALOG_NAMESPACE), _8(BOOTSTRAP_SUPERUSERID), _9(INTERNALlanguageId), _10(1), _11(0), _12(0), _13(0), _14(false), _15(false), _16(false), _17(false), _18('i'), _19(0), _20(1, 701), _21(NULL), _22(NULL), _23(NULL), _24(NULL), _25("dsin"), _26(NULL), _27(NULL), _28(NULL), _29(0), _30(false), _31(NULL), _32(false), _33("sine"), _34('f'), _35(NULL), _36(0), _37(false), _38(NULL), _39(NULL), _40(0)) diff --git a/src/common/backend/catalog/gs_package.cpp b/src/common/backend/catalog/gs_package.cpp index 685d5c322c33ac5f3de35d76e2438833018e8dc8..a0942181a089a89673dad4665f45e20c947223e9 100755 --- a/src/common/backend/catalog/gs_package.cpp +++ b/src/common/backend/catalog/gs_package.cpp @@ -1926,13 +1926,24 @@ bool isSameArgList(CreateFunctionStmt* stmt1, CreateFunctionStmt* stmt2) Type typtup1; Type typtup2; errno_t rc; - if (enable_plpgsql_undefined()) { - typtup1 = LookupTypeNameSupportUndef(NULL, t1, NULL); - typtup2 = LookupTypeNameSupportUndef(NULL, t2, NULL); - } else { - typtup1 = LookupTypeName(NULL, t1, NULL); - typtup2 = LookupTypeName(NULL, t2, NULL); + PG_TRY(); + { + set_use_predefined_pltype(true); + if (enable_plpgsql_undefined()) { + typtup1 = LookupTypeNameSupportUndef(NULL, t1, NULL); + typtup2 = LookupTypeNameSupportUndef(NULL, t2, NULL); + } else { + typtup1 = LookupTypeName(NULL, t1, NULL); + typtup2 = LookupTypeName(NULL, t2, NULL); + } + set_use_predefined_pltype(false); + } + PG_CATCH(); + { + set_use_predefined_pltype(false); + PG_RE_THROW(); } + PG_END_TRY(); bool isTableOf1 = false; bool isTableOf2 = false; Oid baseOid1 = InvalidOid; diff --git a/src/common/backend/catalog/namespace.cpp b/src/common/backend/catalog/namespace.cpp index 6c81107b9437353f0ae1fbded70b19cbfcf50e3b..3a7915a17cc8cbf16de07c4c60c9555a1beb1d4f 100644 --- a/src/common/backend/catalog/namespace.cpp +++ b/src/common/backend/catalog/namespace.cpp @@ -952,15 +952,20 @@ Oid TypenameGetTypidExtended(const char* typname, bool temp_ok) Oid typid; ListCell* l = NULL; List* tempActiveSearchPath = NIL; + bool isPredefinedPLtype = TypeAvailableInProcedure(typname); recomputeNamespacePath(); tempActiveSearchPath = list_copy(u_sess->catalog_cxt.activeSearchPath); + if (IsInitdb || u_sess->attr.attr_common.IsInplaceUpgrade) { + set_use_predefined_pltype(true); + } foreach (l, tempActiveSearchPath) { Oid namespaceId = lfirst_oid(l); /* do not look in temp namespace if temp_ok if false */ - if (!temp_ok && namespaceId == u_sess->catalog_cxt.myTempNamespace) + if ((!temp_ok && namespaceId == u_sess->catalog_cxt.myTempNamespace) || + (isPredefinedPLtype && namespaceId == PG_CATALOG_NAMESPACE)) continue; typid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(typname), ObjectIdGetDatum(namespaceId)); @@ -968,9 +973,18 @@ Oid TypenameGetTypidExtended(const char* typname, bool temp_ok) typid = TryLookForSynonymType(typname, namespaceId); } + /* in procedure, prioritize predefined types, except for subtypes */ + if (isPredefinedPLtype && OidIsValid(typid) && u_sess->plsql_cxt.use_predefined_pltype) { + Type typ = typeidType(typid); + Form_pg_type typtup = (Form_pg_type)GETSTRUCT(typ); + if (typtup->typinput != F_SUBTYPE_IN) { + typid = InvalidOid; + } + ReleaseSysCache(typ); + } + if (OidIsValid(typid)) { - list_free_ext(tempActiveSearchPath); - return typid; + goto typid_found; } } @@ -978,13 +992,24 @@ Oid TypenameGetTypidExtended(const char* typname, bool temp_ok) if (!OidIsValid(typid)) { typid = TryLookForSynonymType(typname, PUB_SYNONYM_NSP_OID); if (OidIsValid(typid)) { - list_free_ext(tempActiveSearchPath); - return typid; + goto typid_found; } } + if (u_sess->plsql_cxt.use_predefined_pltype && isPredefinedPLtype) { + typid = GetSysCacheOid2(TYPENAMENSP, PointerGetDatum(typname), ObjectIdGetDatum(PG_CATALOG_NAMESPACE)); + } + goto typid_found; + +typid_found: + if (IsInitdb || u_sess->attr.attr_common.IsInplaceUpgrade) { + set_use_predefined_pltype(false); + } list_free_ext(tempActiveSearchPath); + if (OidIsValid(typid)) { + return typid; + } /* Not found in path */ return InvalidOid; } diff --git a/src/common/backend/catalog/system_views.sql b/src/common/backend/catalog/system_views.sql index c697703e00c6472485043f4198920405746d0447..b4b0ad50723588f71a0d5a61b3f073a5f1d101e8 100644 --- a/src/common/backend/catalog/system_views.sql +++ b/src/common/backend/catalog/system_views.sql @@ -4715,3 +4715,51 @@ CREATE OR REPLACE FUNCTION pg_catalog.raise_application_error( ) RETURNS void AS '$libdir/plpgsql', 'raise_application_error' LANGUAGE C VOLATILE NOT FENCED; + +CREATE DOMAIN pg_catalog."natural" AS int4 CHECK (VALUE >= 0); +CREATE DOMAIN pg_catalog."naturaln" AS int4 CHECK (VALUE IS NOT NULL AND VALUE >= 0); +CREATE DOMAIN pg_catalog."positive" AS int4 CHECK (VALUE > 0); +CREATE DOMAIN pg_catalog."positiven" AS int4 CHECK (VALUE IS NOT NULL AND VALUE > 0); +CREATE DOMAIN pg_catalog."signtype" AS int4 CHECK (VALUE in (-1, 1, 0)); +CREATE DOMAIN pg_catalog."simple_integer" AS int4 CHECK (VALUE IS NOT NULL); + +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_plus( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_plus(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_sub( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_sub(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_mul( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_mul(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +CREATE OPERATOR pg_catalog.+( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_plus, + commutator=operator(pg_catalog.+) +); + +CREATE OPERATOR pg_catalog.-( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_sub +); + +CREATE OPERATOR pg_catalog.*( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_mul, + commutator=operator(pg_catalog.*) +); \ No newline at end of file diff --git a/src/common/backend/parser/parse_func.cpp b/src/common/backend/parser/parse_func.cpp index 4c5e67e86129f1e58cbaedd4d4637892fbcc5e51..57379d932dab69ba6221011778646a962bfc65f0 100644 --- a/src/common/backend/parser/parse_func.cpp +++ b/src/common/backend/parser/parse_func.cpp @@ -2402,12 +2402,23 @@ Oid LookupFuncNameTypeNames(List* funcname, List* argtypes, bool noError) FUNC_MAX_ARGS))); args_item = list_head(argtypes); - for (i = 0; i < argcount; i++) { - TypeName* t = (TypeName*)lfirst(args_item); + PG_TRY(); + { + set_use_predefined_pltype(true); + for (i = 0; i < argcount; i++) { + TypeName* t = (TypeName*)lfirst(args_item); - argoids[i] = LookupTypeNameOid(t); - args_item = lnext(args_item); + argoids[i] = LookupTypeNameOid(t); + args_item = lnext(args_item); + } + set_use_predefined_pltype(false); + } + PG_CATCH(); + { + set_use_predefined_pltype(false); + PG_RE_THROW(); } + PG_END_TRY(); return LookupFuncName(funcname, argcount, argoids, noError); } diff --git a/src/common/backend/utils/adt/int.cpp b/src/common/backend/utils/adt/int.cpp index 9543567c585c2f968672a027f5cdd475f6049012..179ea982607028d30569c1df225ec8d9936befce 100644 --- a/src/common/backend/utils/adt/int.cpp +++ b/src/common/backend/utils/adt/int.cpp @@ -77,6 +77,12 @@ static void CheckSpaceAndDotInternal(char& digitAfterDot, const char** ptr, bool } } +static inline int64 SimpleIntegerOverflow(int64 n) +{ + return (n < 0 ? (n & 0x00000000FFFFFFFF) : + n > 0 ? (-((-n) & 0x00000000FFFFFFFF)) : n); +} + template int64 PgStrToIntInternal(const char* s, bool errOk, uint64 max, int64 min, const char* typname) { @@ -1926,3 +1932,63 @@ Datum text_int4(PG_FUNCTION_ARGS) PG_RETURN_DATUM(result); } + +Datum simple_integer_plus(PG_FUNCTION_ARGS) +{ + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) { + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("value for domain simple_integer violates check constraint \"simple_integer_check\""))); + } + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + int32 result; + + if (pg_add_s32_overflow(arg1, arg2, &result)) { + int64 result64; + pg_add_s64_overflow((int64)arg1, (int64)arg2, &result64); + result = (int32)SimpleIntegerOverflow(result64); + } + + PG_RETURN_INT32(result); +} + +Datum simple_integer_sub(PG_FUNCTION_ARGS) +{ + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) { + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("value for domain simple_integer violates check constraint \"simple_integer_check\""))); + } + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + int32 result; + + if (pg_sub_s32_overflow(arg1, arg2, &result)) { + int64 result64; + pg_sub_s64_overflow((int64)arg1, (int64)arg2, &result64); + result = (int32)SimpleIntegerOverflow(result64); + } + + PG_RETURN_INT32(result); +} + +Datum simple_integer_mul(PG_FUNCTION_ARGS) +{ + if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) { + ereport(ERROR, + (errcode(ERRCODE_CHECK_VIOLATION), + errmsg("value for domain simple_integer violates check constraint \"simple_integer_check\""))); + } + int32 arg1 = PG_GETARG_INT32(0); + int32 arg2 = PG_GETARG_INT32(1); + int32 result; + + if (pg_mul_s32_overflow(arg1, arg2, &result)) { + int64 result64; + pg_mul_s64_overflow((int64)arg1, (int64)arg2, &result64); + result = (int32)SimpleIntegerOverflow(result64); + } + + PG_RETURN_INT32(result); +} \ No newline at end of file diff --git a/src/common/backend/utils/init/globals.cpp b/src/common/backend/utils/init/globals.cpp index 57daef93064b577a6070aff6f54a211e0bd0e153..99d1a880d843bf2e4a12c6b2a10d2f3d637004c8 100644 --- a/src/common/backend/utils/init/globals.cpp +++ b/src/common/backend/utils/init/globals.cpp @@ -77,7 +77,7 @@ bool will_shutdown = false; * ********************************************/ -const uint32 GRAND_VERSION_NUM = 93044; +const uint32 GRAND_VERSION_NUM = 93045; /******************************************** * 2.VERSION NUM FOR EACH FEATURE diff --git a/src/common/pl/plpgsql/src/gram.y b/src/common/pl/plpgsql/src/gram.y index d88a71f6996e57523f95e7ceb567907ef60f6ec5..79be325e5291715077e4779c26d55163e978444e 100755 --- a/src/common/pl/plpgsql/src/gram.y +++ b/src/common/pl/plpgsql/src/gram.y @@ -13220,24 +13220,27 @@ parse_datatype(const char *string, int location) u_sess->plsql_cxt.plpgsql_yylloc = plpgsql_yylloc; /* Let the main parser try to parse it under standard SQL rules */ TypeDependExtend* typeDependExtend = NULL; - if (enable_plpgsql_gsdependency()) { - InstanceTypeNameDependExtend(&typeDependExtend); - CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; - PG_TRY(); - { + CreatePlsqlType oldCreatePlsqlType = u_sess->plsql_cxt.createPlsqlType; + PG_TRY(); + { + set_use_predefined_pltype(true); + if (enable_plpgsql_gsdependency()) { + InstanceTypeNameDependExtend(&typeDependExtend); set_create_plsql_type_not_check_nsp_oid(); parseTypeString(string, &type_id, &typmod, typeDependExtend); set_create_plsql_type(oldCreatePlsqlType); + } else { + parseTypeString(string, &type_id, &typmod, typeDependExtend); } - PG_CATCH(); - { - set_create_plsql_type(oldCreatePlsqlType); - PG_RE_THROW(); - } - PG_END_TRY(); - } else { - parseTypeString(string, &type_id, &typmod, typeDependExtend); + set_use_predefined_pltype(false); + } + PG_CATCH(); + { + set_create_plsql_type(oldCreatePlsqlType); + set_use_predefined_pltype(false); + PG_RE_THROW(); } + PG_END_TRY(); (void)MemoryContextSwitchTo(oldCxt); diff --git a/src/common/pl/plpgsql/src/pl_exec.cpp b/src/common/pl/plpgsql/src/pl_exec.cpp index 5c0696258215e696b4b206f4c7f984739d8228a0..1d4510d41472b61b2952978129ae0dc4ac9dcad6 100644 --- a/src/common/pl/plpgsql/src/pl_exec.cpp +++ b/src/common/pl/plpgsql/src/pl_exec.cpp @@ -12166,7 +12166,18 @@ static Datum exec_eval_expr(PLpgSQL_execstate* estate, PLpgSQL_expr* expr, bool* * If first time through, create a plan for this expression. */ if (expr->plan == NULL) { - exec_prepare_plan(estate, expr, 0); + PG_TRY(); + { + set_use_predefined_pltype(true); + exec_prepare_plan(estate, expr, 0); + set_use_predefined_pltype(false); + } + PG_CATCH(); + { + set_use_predefined_pltype(false); + PG_RE_THROW(); + } + PG_END_TRY(); } if (ENABLE_CN_GPC && g_instance.plan_cache->CheckRecreateSPICachePlan(expr->plan)) { g_instance.plan_cache->RecreateSPICachePlan(expr->plan); diff --git a/src/gausskernel/optimizer/commands/functioncmds.cpp b/src/gausskernel/optimizer/commands/functioncmds.cpp index a5080d4a89b91e954aab05ecfe2e45b15c3bc134..eb982d91833692762e33319112bd1660032c4d4d 100644 --- a/src/gausskernel/optimizer/commands/functioncmds.cpp +++ b/src/gausskernel/optimizer/commands/functioncmds.cpp @@ -348,14 +348,25 @@ void examine_parameter_list(List* parameters, Oid languageOid, const char* query AclResult aclresult; char* objname = NULL; objname = strVal(linitial(t->names)); - if (enable_plpgsql_gsdependency()) { - typtup = LookupTypeName(NULL, t, NULL, true, (*type_depend_extend) + i); - if (NULL != has_undefined && !*has_undefined && (*type_depend_extend)[i].dependUndefined) { - *has_undefined = true; + PG_TRY(); + { + set_use_predefined_pltype(true); + if (enable_plpgsql_gsdependency()) { + typtup = LookupTypeName(NULL, t, NULL, true, (*type_depend_extend) + i); + if (NULL != has_undefined && !*has_undefined && (*type_depend_extend)[i].dependUndefined) { + *has_undefined = true; + } + } else { + typtup = LookupTypeName(NULL, t, NULL); } - } else { - typtup = LookupTypeName(NULL, t, NULL); + set_use_predefined_pltype(false); + } + PG_CATCH(); + { + set_use_predefined_pltype(false); + PG_RE_THROW(); } + PG_END_TRY(); int typ_tup_status = GetTypeTupStatus(typtup); if (NormalTypeTup != typ_tup_status) { toid = findPackageParameter(objname); @@ -1303,8 +1314,10 @@ ObjectAddress CreateFunction(CreateFunctionStmt* stmt, const char* queryString, if (stmt->returnType) { /* explicit RETURNS clause */ InstanceTypeNameDependExtend(&ret_type_depend_ext); + set_use_predefined_pltype(true); compute_return_type(stmt->returnType, languageOid, &prorettype, &returnsSet, fenced, stmt->startLineNumber, ret_type_depend_ext, false, isPipelined); + set_use_predefined_pltype(false); } else if (OidIsValid(requiredResultType)) { /* default RETURNS clause from OUT parameters */ InstanceTypeNameDependExtend(&ret_type_depend_ext); @@ -1324,6 +1337,7 @@ ObjectAddress CreateFunction(CreateFunctionStmt* stmt, const char* queryString, { set_create_plsql_type(oldCreatePlsqlType); u_sess->plsql_cxt.curr_object_nspoid = old_curr_object_nspoid; + set_use_predefined_pltype(false); PG_RE_THROW(); } PG_END_TRY(); diff --git a/src/gausskernel/optimizer/commands/typecmds.cpp b/src/gausskernel/optimizer/commands/typecmds.cpp index 18825f0c2589be4e4f71c83710681b365db005df..3388287f19ea544d3bff24599f075b9b2f0ed235 100644 --- a/src/gausskernel/optimizer/commands/typecmds.cpp +++ b/src/gausskernel/optimizer/commands/typecmds.cpp @@ -792,6 +792,7 @@ ObjectAddress DefineDomain(CreateDomainStmt* stmt) char alignment; char storage; char typtype; + Oid typarray; Datum datum; bool isnull = false; char* defaultValue = NULL; @@ -912,6 +913,10 @@ ObjectAddress DefineDomain(CreateDomainStmt* stmt) /* Array element Delimiter */ delimiter = baseType->typdelim; + /* Array type */ + typarray = domainNamespace == PG_CATALOG_NAMESPACE && TypeAvailableInProcedure(domainName) ? + baseType->typarray : InvalidOid; + /* I/O Functions */ inputProcedure = F_DOMAIN_IN; outputProcedure = baseType->typoutput; @@ -1088,7 +1093,7 @@ ObjectAddress DefineDomain(CreateDomainStmt* stmt) analyzeProcedure, /* analyze procedure */ InvalidOid, /* no array element type */ false, /* this isn't an array */ - InvalidOid, /* no arrays for domains (yet) */ + typarray, /* no arrays for domains (yet) */ basetypeoid, /* base type ID */ defaultValue, /* default type value (text) */ defaultValueBin, /* default type value (binary) */ diff --git a/src/gausskernel/process/threadpool/knl_session.cpp b/src/gausskernel/process/threadpool/knl_session.cpp index 030ff32e56939a1c7e3337ad9122c8240779004f..4a1e9b4a9e8ed5a340e8e205a93b586d2cbce79d 100755 --- a/src/gausskernel/process/threadpool/knl_session.cpp +++ b/src/gausskernel/process/threadpool/knl_session.cpp @@ -1963,3 +1963,8 @@ bool set_is_create_plsql_type() } return true; } + +void set_use_predefined_pltype(bool use_predefined_pltype) +{ + u_sess->plsql_cxt.use_predefined_pltype = use_predefined_pltype; +} diff --git a/src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_93_045.sql b/src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_93_045.sql new file mode 100644 index 0000000000000000000000000000000000000000..267b5cd46ddb8457556c415986ef300c2e5d5da8 --- /dev/null +++ b/src/include/catalog/upgrade_sql/rollback_catalog_maindb/rollback-post_catalog_maindb_93_045.sql @@ -0,0 +1,43 @@ +-------------------------------------------------------------- +-- delete pg_operator +-------------------------------------------------------------- +DO $$ +DECLARE +ans boolean; +BEGIN + select case when count(*)=1 then true else false end as ans from (select * from pg_type where typname = 'simple_integer' limit 1) into ans; + if ans = true then + DROP OPERATOR IF EXISTS pg_catalog.+(simple_integer, simple_integer) CASCADE; + DROP OPERATOR IF EXISTS pg_catalog.-(simple_integer, simple_integer) CASCADE; + DROP OPERATOR IF EXISTS pg_catalog.*(simple_integer, simple_integer) CASCADE; + end if; +END$$; + +-------------------------------------------------------------- +-- delete builtin funcs +-------------------------------------------------------------- +DO $$ +DECLARE +ans boolean; +BEGIN + select case when count(*)=1 then true else false end as ans from (select * from pg_type where typname = 'simple_integer' limit 1) into ans; + if ans = true then + DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(simple_integer, simple_integer); + DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(simple_integer, simple_integer); + DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(simple_integer,simple_integer); + end if; +END$$; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(integer, integer); +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(integer, integer); +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(integer, integer); + +-------------------------------------------------------------- +-- delete type +-------------------------------------------------------------- +DROP DOMAIN IF EXISTS pg_catalog."natural"; +DROP DOMAIN IF EXISTS pg_catalog."naturaln"; +DROP DOMAIN IF EXISTS pg_catalog."positive"; +DROP DOMAIN IF EXISTS pg_catalog."positiven"; +DROP DOMAIN IF EXISTS pg_catalog."signtype"; +DROP DOMAIN IF EXISTS pg_catalog."simple_integer"; \ No newline at end of file diff --git a/src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_93_045.sql b/src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_93_045.sql new file mode 100644 index 0000000000000000000000000000000000000000..267b5cd46ddb8457556c415986ef300c2e5d5da8 --- /dev/null +++ b/src/include/catalog/upgrade_sql/rollback_catalog_otherdb/rollback-post_catalog_otherdb_93_045.sql @@ -0,0 +1,43 @@ +-------------------------------------------------------------- +-- delete pg_operator +-------------------------------------------------------------- +DO $$ +DECLARE +ans boolean; +BEGIN + select case when count(*)=1 then true else false end as ans from (select * from pg_type where typname = 'simple_integer' limit 1) into ans; + if ans = true then + DROP OPERATOR IF EXISTS pg_catalog.+(simple_integer, simple_integer) CASCADE; + DROP OPERATOR IF EXISTS pg_catalog.-(simple_integer, simple_integer) CASCADE; + DROP OPERATOR IF EXISTS pg_catalog.*(simple_integer, simple_integer) CASCADE; + end if; +END$$; + +-------------------------------------------------------------- +-- delete builtin funcs +-------------------------------------------------------------- +DO $$ +DECLARE +ans boolean; +BEGIN + select case when count(*)=1 then true else false end as ans from (select * from pg_type where typname = 'simple_integer' limit 1) into ans; + if ans = true then + DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(simple_integer, simple_integer); + DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(simple_integer, simple_integer); + DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(simple_integer,simple_integer); + end if; +END$$; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(integer, integer); +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(integer, integer); +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(integer, integer); + +-------------------------------------------------------------- +-- delete type +-------------------------------------------------------------- +DROP DOMAIN IF EXISTS pg_catalog."natural"; +DROP DOMAIN IF EXISTS pg_catalog."naturaln"; +DROP DOMAIN IF EXISTS pg_catalog."positive"; +DROP DOMAIN IF EXISTS pg_catalog."positiven"; +DROP DOMAIN IF EXISTS pg_catalog."signtype"; +DROP DOMAIN IF EXISTS pg_catalog."simple_integer"; \ No newline at end of file diff --git a/src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_93_045.sql b/src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_93_045.sql new file mode 100644 index 0000000000000000000000000000000000000000..2da101933e456aef12fbd1819490b450a78677c1 --- /dev/null +++ b/src/include/catalog/upgrade_sql/upgrade_catalog_maindb/upgrade-post_catalog_maindb_93_045.sql @@ -0,0 +1,67 @@ +-- functions +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(integer, integer) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3361; +CREATE FUNCTION pg_catalog.simple_integer_mul(integer, integer) +RETURNS integer LANGUAGE INTERNAL IMMUTABLE as 'simple_integer_mul'; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(integer, integer) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3362; +CREATE FUNCTION pg_catalog.simple_integer_plus(integer, integer) +RETURNS integer LANGUAGE INTERNAL IMMUTABLE as 'simple_integer_plus'; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(integer, integer) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3364; +CREATE FUNCTION pg_catalog.simple_integer_sub(integer, integer) +RETURNS integer LANGUAGE INTERNAL IMMUTABLE as 'simple_integer_sub'; + +-- types +CREATE DOMAIN pg_catalog."natural" AS int4 CHECK (VALUE >= 0); +CREATE DOMAIN pg_catalog."naturaln" AS int4 CHECK (VALUE IS NOT NULL AND VALUE >= 0); +CREATE DOMAIN pg_catalog."positive" AS int4 CHECK (VALUE > 0); +CREATE DOMAIN pg_catalog."positiven" AS int4 CHECK (VALUE IS NOT NULL AND VALUE > 0); +CREATE DOMAIN pg_catalog."signtype" AS int4 CHECK (VALUE in (-1, 1, 0)); +CREATE DOMAIN pg_catalog."simple_integer" AS int4 CHECK (VALUE IS NOT NULL); + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(simple_integer, simple_integer) CASCADE; +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_plus( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_plus(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(simple_integer, simple_integer) CASCADE; +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_sub( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_sub(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(simple_integer, simple_integer) CASCADE; +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_mul( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_mul(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +-- operators +DROP OPERATOR IF EXISTS pg_catalog.+(simple_integer, simple_integer) CASCADE; +CREATE OPERATOR pg_catalog.+( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_plus, + commutator=operator(pg_catalog.+) +); + +DROP OPERATOR IF EXISTS pg_catalog.-(simple_integer, simple_integer) CASCADE; +CREATE OPERATOR pg_catalog.-(leftarg = simple_integer, rightarg = simple_integer, procedure = simple_integer_sub); + +DROP OPERATOR IF EXISTS pg_catalog.*(simple_integer, simple_integer) CASCADE; +CREATE OPERATOR pg_catalog.*( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_mul, + commutator=operator(pg_catalog.*) +); \ No newline at end of file diff --git a/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_93_045.sql b/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_93_045.sql new file mode 100644 index 0000000000000000000000000000000000000000..2da101933e456aef12fbd1819490b450a78677c1 --- /dev/null +++ b/src/include/catalog/upgrade_sql/upgrade_catalog_otherdb/upgrade-post_catalog_otherdb_93_045.sql @@ -0,0 +1,67 @@ +-- functions +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(integer, integer) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3361; +CREATE FUNCTION pg_catalog.simple_integer_mul(integer, integer) +RETURNS integer LANGUAGE INTERNAL IMMUTABLE as 'simple_integer_mul'; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(integer, integer) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3362; +CREATE FUNCTION pg_catalog.simple_integer_plus(integer, integer) +RETURNS integer LANGUAGE INTERNAL IMMUTABLE as 'simple_integer_plus'; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(integer, integer) CASCADE; +SET LOCAL inplace_upgrade_next_system_object_oids = IUO_PROC, 3364; +CREATE FUNCTION pg_catalog.simple_integer_sub(integer, integer) +RETURNS integer LANGUAGE INTERNAL IMMUTABLE as 'simple_integer_sub'; + +-- types +CREATE DOMAIN pg_catalog."natural" AS int4 CHECK (VALUE >= 0); +CREATE DOMAIN pg_catalog."naturaln" AS int4 CHECK (VALUE IS NOT NULL AND VALUE >= 0); +CREATE DOMAIN pg_catalog."positive" AS int4 CHECK (VALUE > 0); +CREATE DOMAIN pg_catalog."positiven" AS int4 CHECK (VALUE IS NOT NULL AND VALUE > 0); +CREATE DOMAIN pg_catalog."signtype" AS int4 CHECK (VALUE in (-1, 1, 0)); +CREATE DOMAIN pg_catalog."simple_integer" AS int4 CHECK (VALUE IS NOT NULL); + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_plus(simple_integer, simple_integer) CASCADE; +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_plus( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_plus(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_sub(simple_integer, simple_integer) CASCADE; +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_sub( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_sub(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +DROP FUNCTION IF EXISTS pg_catalog.simple_integer_mul(simple_integer, simple_integer) CASCADE; +CREATE OR REPLACE FUNCTION pg_catalog.simple_integer_mul( + IN a simple_integer, + IN b simple_integer +) RETURNS simple_integer +AS $$ SELECT pg_catalog.simple_integer_mul(a::integer, b::integer)::simple_integer $$ +LANGUAGE SQL IMMUTABLE NOT FENCED; + +-- operators +DROP OPERATOR IF EXISTS pg_catalog.+(simple_integer, simple_integer) CASCADE; +CREATE OPERATOR pg_catalog.+( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_plus, + commutator=operator(pg_catalog.+) +); + +DROP OPERATOR IF EXISTS pg_catalog.-(simple_integer, simple_integer) CASCADE; +CREATE OPERATOR pg_catalog.-(leftarg = simple_integer, rightarg = simple_integer, procedure = simple_integer_sub); + +DROP OPERATOR IF EXISTS pg_catalog.*(simple_integer, simple_integer) CASCADE; +CREATE OPERATOR pg_catalog.*( + leftarg = simple_integer, + rightarg = simple_integer, + procedure = simple_integer_mul, + commutator=operator(pg_catalog.*) +); \ No newline at end of file diff --git a/src/include/knl/knl_session.h b/src/include/knl/knl_session.h index 679a91b0c8e5f28eeeec76671d1211f5a87a31c7..9d8635169160d48be3a35c1fef4b41d5b51bf765 100644 --- a/src/include/knl/knl_session.h +++ b/src/include/knl/knl_session.h @@ -1764,6 +1764,7 @@ typedef struct knl_u_plpgsql_context { bool is_exec_autonomous; bool in_package_function_compile; bool is_alter_compile_stmt; + bool use_predefined_pltype; CreatePlsqlType createPlsqlType; FunctionStyleType functionStyleType; List* pkg_var_info; @@ -3271,6 +3272,7 @@ extern void set_function_style_a(); extern void set_function_style_pg(); extern bool set_is_create_plsql_type(); extern void set_is_create_pkg_function(bool is_create_pkg_function); +extern void set_use_predefined_pltype(bool use_predefined_pltype); extern THR_LOCAL knl_session_context* u_sess; diff --git a/src/include/parser/parse_type.h b/src/include/parser/parse_type.h index badf7ddb2a7a3cdcc331b64a4c07fb083979c3c1..7be326570e1d60c713f2f6aa70b18fbc4cba9e5c 100644 --- a/src/include/parser/parse_type.h +++ b/src/include/parser/parse_type.h @@ -69,6 +69,12 @@ extern char* CastPackageTypeName(const char* typName, Oid pkgOid, bool isPackag extern Oid LookupTypeInFunc(const char* typeName); extern bool IsBinaryType(Oid typid); typedef bool (*isBinaryType)(Oid typid); +extern inline bool TypeAvailableInProcedure(const char *name) +{ + return (strcmp(name, "natural") == 0 || strcmp(name, "naturaln") == 0 || + strcmp(name, "positive") == 0 || strcmp(name, "positiven") == 0 || + strcmp(name, "signtype") == 0 || strcmp(name, "simple_integer") == 0); +} #define ISCOMPLEX(typeid) (typeidTypeRelid(typeid) != InvalidOid) extern void check_type_supports_multi_charset(Oid typid, bool allow_array); extern char* ParseTypeName(const char* typName, Oid pkgOid); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 0a57b53d549b7ca4e69ca7a61651dacfa3b893ae..102be3afba39488d7b15dc952c0af25a6f07f31f 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -423,6 +423,9 @@ extern Datum generate_series_int4(PG_FUNCTION_ARGS); extern Datum generate_series_step_int4(PG_FUNCTION_ARGS); extern int2vector* buildint2vector(const int2* int2s, int n); extern int2vector* int2vectorCopy(int2vector* from); +extern Datum simple_integer_mul(PG_FUNCTION_ARGS); +extern Datum simple_integer_plus(PG_FUNCTION_ARGS); +extern Datum simple_integer_sub(PG_FUNCTION_ARGS); /* encoding.cpp */ extern Datum encode_plan_node(PG_FUNCTION_ARGS); /* ml_model.cpp */ diff --git a/src/test/regress/expected/plpgsql_predefined_types.out b/src/test/regress/expected/plpgsql_predefined_types.out new file mode 100644 index 0000000000000000000000000000000000000000..55df898ae166b5ad343666b1ce655535747b6173 --- /dev/null +++ b/src/test/regress/expected/plpgsql_predefined_types.out @@ -0,0 +1,815 @@ +CREATE DATABASE test_predefined_pltype; +\c test_predefined_pltype; +-- natural +DECLARE + m natural := 1; + n natural := 2; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +INFO: m: 3 +-- invalid value +DECLARE + m natural := -1; + n natural := 2; +BEGIN + m := m - n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain "natural" violates check constraint "natural_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +-- Result of such kind of testcases is wrong by now. +-- An error is expected when assigning -3 to n during typecast. +-- Wait until the bug is fixed to correct it. +DECLARE + m text := '-3'; + n natural := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +INFO: n: -3 +-- overflow +DECLARE + m natural := 1; + n natural := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m natural := 0; + n natural := 2147483647; +BEGIN + m := m - n - 2; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := 2147483649; + n natural := 0; +BEGIN + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := -2147483649; + n natural := 0; +BEGIN + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +-- naturaln +DECLARE + m naturaln := 1; + n naturaln := 2; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +INFO: m: 3 +-- invalid value +DECLARE + m naturaln := -1; + n naturaln := 2; +BEGIN + m := m - n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain naturaln violates check constraint "naturaln_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m naturaln := NULL; + n naturaln := 2; +BEGIN + m := m - n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain naturaln violates check constraint "naturaln_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m float := -3.2; + n naturaln := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +INFO: n: -3 +DECLARE + m float := NULL; + n naturaln := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +ERROR: value for domain naturaln violates check constraint "naturaln_check" +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +-- overflow +DECLARE + m naturaln := 1; + n naturaln := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m naturaln := 0; + n naturaln := 2147483647; +BEGIN + m := m - n - 2; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := 2147483649; + n naturaln := 0; +BEGIN + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := -2147483649; + n naturaln := 0; +BEGIN + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +-- positive +DECLARE + m positive := 5; + n positive := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +INFO: m: 11 +-- invalid value +DECLARE + m positive := 0; + n positive := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain positive violates check constraint "positive_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m NUMBER(18) := -3; + n positive := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +INFO: n: -3 +-- overflow +DECLARE + m positive := 1; + n positive := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m positive := 1; + n positive := 2147483647; +BEGIN + m := m - n - 3; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := 2147483648; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := -2147483649; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +-- positiven +DECLARE + m positiven := 5; + n positiven := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +INFO: m: 11 +-- invalid value +DECLARE + m positiven := 0; + n positiven := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain positiven violates check constraint "positiven_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m positiven := NULL; + n positiven := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain positiven violates check constraint "positiven_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m NUMBER(18) := -3; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +INFO: n: -3 +DECLARE + m text := NULL; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +ERROR: value for domain positiven violates check constraint "positiven_check" +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +-- overflow +DECLARE + m positiven := 1; + n positiven := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m positiven := 1; + n positiven := 2147483647; +BEGIN + m := m - n - 3; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := 2147483648; + n positiven := 1; +BEGIN + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m NUMBER(18) := -2147483649; + n positiven := 1; +BEGIN + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +-- signtype +DECLARE + x signtype := 0; + y signtype := 1; + z signtype := -1; +BEGIN + z := x + y + z; + raise info 'm: %', z; +END; +/ +INFO: m: 0 +-- invalid value +DECLARE + x signtype := 0; + y signtype := 1; + z signtype := -1; +BEGIN + z := x + y - z; + raise info 'm: %', z; +END; +/ +ERROR: value for domain signtype violates check constraint "signtype_check" +CONTEXT: PL/pgSQL function inline_code_block line 5 at assignment +DECLARE + m text := '2'; + n signtype := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ +INFO: n: 2 +-- simple_integer +DECLARE + m simple_integer := -9; + n simple_integer := 10; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +INFO: m: 1 +-- invalid value +DECLARE + m simple_integer := NULL; + n simple_integer := 10; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: value for domain simple_integer violates check constraint "simple_integer_check" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m NUMBER(18) := 0; + n SIMPLE_INTEGER := 0; +BEGIN + m := NULL; + n := m; +END; +/ +ERROR: value for domain simple_integer violates check constraint "simple_integer_check" +CONTEXT: PL/pgSQL function inline_code_block line 5 at assignment +-- overflow +DECLARE + m simple_integer := 1; + n simple_integer := 2147483648; -- ERROR +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m simple_integer := 1; + n simple_integer := -2147483649; -- ERROR +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m simple_integer := 2; + n simple_integer := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; -- -2147483647 +END; +/ +INFO: m: -2147483647 +DECLARE + m simple_integer := 2147483647; + n simple_integer := 2147483647; +BEGIN + m := m * n; + raise info 'm: %', m; -- 1 +END; +/ +INFO: m: 1 +DECLARE + m simple_integer := -2; + n simple_integer := 2147483647; +BEGIN + m := m - n; + raise info 'm: %', m; -- 2147483647 +END; +/ +INFO: m: 2147483647 +DECLARE + m simple_integer := -2; + n simple_integer := 2147483647; +BEGIN + m := n / m; + raise info 'm: %', m; -- -1073741824 +END; +/ +INFO: m: -1073741824 +DECLARE + m simple_integer := -1; + n simple_integer := -2147483648; +BEGIN + m := n / m; + raise info 'm: %', m; -- ERROR +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 4 at assignment +DECLARE + m simple_integer := -2; + n simple_integer := 2147483647; +BEGIN + m := n % m; + raise info 'm: %', m; +END; +/ +INFO: m: 1 +DECLARE + m NUMBER(18) := 0; + n SIMPLE_INTEGER := 0; +BEGIN + m := -2147483649; + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 5 at assignment +DECLARE + m NUMBER(18) := 0; + n SIMPLE_INTEGER := 0; +BEGIN + m := 2147483649; + n := m; +END; +/ +ERROR: integer out of range +CONTEXT: PL/pgSQL function inline_code_block line 5 at assignment +-- scope of effect +DROP TYPE IF EXISTS simple_integer; -- ERROR +NOTICE: type "simple_integer" does not exist, skipping +ALTER DOMAIN positiven DROP NOT NULL; -- ERROR +ERROR: type "positiven" does not exist +SELECT oid, typname FROM pg_type WHERE typname='simple_integer' ORDER BY oid ASC; + oid | typname +-------+---------------- +--?.*simple_integer +(1 row) + +SELECT 1::simple_integer; -- ERROR +ERROR: type "simple_integer" does not exist +LINE 1: SELECT 1::simple_integer; + ^ +CONTEXT: referenced column: simple_integer +CREATE TYPE simple_integer AS (a int, b varchar(10)); +SELECT oid, typname FROM pg_type WHERE typname='simple_integer'; + oid | typname +-------+---------------- +--?.*simple_integer +--?.*simple_integer +(2 rows) + +SELECT (1, 'a')::simple_integer; + row +------- + (1,a) +(1 row) + +SELECT (1, 'a')::simple_integer + (2, 'b')::simple_integer; -- ERROR +ERROR: operator does not exist: public.simple_integer + public.simple_integer +LINE 1: SELECT (1, 'a')::simple_integer + (2, 'b')::simple_integer; + ^ +HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts. +DECLARE + m simple_integer; +BEGIN + m.a := 1; -- ERROR + m.b := 'a'; +END; +/ +ERROR: "m.a" is not a known variable +LINE 3: m.a := 1; -- ERROR + ^ +QUERY: DECLARE m simple_integer; +BEGIN + m.a := 1; -- ERROR + m.b := 'a'; +END +DROP TYPE simple_integer; +SELECT oid, typname FROM pg_type WHERE typname='simple_integer'; + oid | typname +-------+---------------- +--?.*simple_integer +(1 row) + +CREATE DOMAIN positiven as varchar(10); +SELECT 'test'::positiven; + positiven +----------- + test +(1 row) + +DECLARE + m positiven := 1; + n positiven := 'a'; -- ERROR +BEGIN + m := 2; + n := 'b'; + raise info 'm: %, n: %', m, n; +END; +/ +ERROR: invalid input syntax for integer: "a" +CONTEXT: PL/pgSQL function inline_code_block line 3 during statement block local variable initialization +DECLARE + m positive := 1; + TYPE positive IS varray(5) of natural; + arr positive; +BEGIN + m := 2; + arr(1) := 1; + raise info 'm: %, arr(1): %', m, arr(1); +END; +/ +INFO: m: 2, arr(1): 1 +DECLARE + m naturaln := 1; + SUBTYPE naturaln IS INTEGER; + n naturaln := -2; +BEGIN + m := 2; + n := -5; + raise info 'm: %, n: %', m, n; +END; +/ +INFO: m: 2, n: -5 +CREATE OR REPLACE FUNCTION func1(a positiven) RETURNS positiven AS +$$ +BEGIN + a := a + 1; + RETURN a; +END +$$ +LANGUAGE 'plpgsql'; +SELECT func1(3); + func1 +------- + 4 +(1 row) + +SELECT func1(0); -- ERROR +ERROR: value for domain positiven violates check constraint "positiven_check" +CONTEXT: referenced column: func1 +SELECT func1(NULL); -- ERROR +ERROR: value for domain positiven violates check constraint "positiven_check" +CONTEXT: referenced column: func1 +DROP FUNCTION IF EXISTS func2; +NOTICE: function func2() does not exist, skipping +ALTER FUNCTION func1(positiven) RENAME TO func2; +SELECT func1(3); +ERROR: function func1(integer) does not exist +LINE 1: SELECT func1(3); + ^ +HINT: No function matches the given name and argument types. You might need to add explicit type casts. +CONTEXT: referenced column: func1 +SELECT func2(3); + func2 +------- + 4 +(1 row) + +CREATE OR REPLACE PROCEDURE proc1(a signtype) AS +BEGIN + a := -a; + raise info 'a: %', a; +END; +/ +CALL proc1(1); +INFO: a: -1 + proc1 +------- + +(1 row) + +CALL proc1(2); -- ERROR +ERROR: value for domain signtype violates check constraint "signtype_check" +DROP SCHEMA IF EXISTS schem1; +NOTICE: schema "schem1" does not exist, skipping +CREATE SCHEMA schem1; +ALTER PROCEDURE proc1(signtype) SET SCHEMA schem1; +CALL proc1(1); +ERROR: function "proc1" doesn't exist +CALL schem1.proc1(1); +INFO: a: -1 + proc1 +------- + +(1 row) + +DROP FUNCTION func2(positiven); +DROP PROCEDURE schem1.proc1(signtype); +DROP SCHEMA schem1; +CREATE OR REPLACE PACKAGE pkg1 AS + TYPE naturaln IS TABLE OF natural; + tb naturaln; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END pkg1; +/ +CREATE OR REPLACE PACKAGE BODY pkg1 AS + FUNCTION func1(a simple_integer) RETURN simple_integer IS + BEGIN + a := a + 1; + tb(1) := a; + raise info 'tb(1): %', tb(1); + RETURN a; + END func1; +END pkg1; +/ +SELECT pkg1.func1(-3); +INFO: tb(1): -2 +CONTEXT: referenced column: func1 + func1 +------- + -2 +(1 row) + +DROP PACKAGE pkg1; +NOTICE: drop cascades to function public.func1(simple_integer) +-- recover after exception +DECLARE + a natural := 1; + b x.y.z.s.t := 1; +BEGIN + a := 2; +END; +/ +ERROR: improper qualified name (too many dotted names): x.y.z.s.t +LINE 2: b x.y.z.s.t := 1; + ^ +QUERY: DECLARE a natural := 1; + b x.y.z.s.t := 1; +BEGIN + a := 2; +END +SELECT 2::natural; +ERROR: type "natural" does not exist +LINE 1: SELECT 2::natural; + ^ +CONTEXT: referenced column: natural +CREATE OR REPLACE FUNCTION func1(a positiven) RETURNS x.y.z.s.t AS +$$ +BEGIN + a := a + 1; + RETURN a; +END +$$ +LANGUAGE 'plpgsql'; +ERROR: improper qualified name (too many dotted names): x.y.z.s.t +SELECT 2::positive; +ERROR: type "positive" does not exist +LINE 1: SELECT 2::positive; + ^ +CONTEXT: referenced column: positive +CREATE OR REPLACE PROCEDURE proc1(a signtype, b x.y.z.s.t) AS +BEGIN + a := -a; + raise info 'a: %', a; +END; +/ +ERROR: improper qualified name (too many dotted names): x.y.z.s.t +SELECT 2::simple_integer; +ERROR: type "simple_integer" does not exist +LINE 1: SELECT 2::simple_integer; + ^ +CONTEXT: referenced column: simple_integer +CREATE OR REPLACE PACKAGE pkg1 AS + TYPE naturaln IS TABLE OF natural; + tb naturaln; + ab x.y.z.s.t; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END pkg1; +/ +ERROR: improper qualified name (too many dotted names): x.y.z.s.t +LINE 3: ab x.y.z.s.t; + ^ +QUERY: PACKAGE DECLARE TYPE naturaln IS TABLE OF natural; + tb naturaln; + ab x.y.z.s.t; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END +CONTEXT: compilation of PL/pgSQL package near line 3 +SELECT 1::signtype; +ERROR: type "signtype" does not exist +LINE 1: SELECT 1::signtype; + ^ +CONTEXT: referenced column: signtype +CREATE OR REPLACE PACKAGE pkg1 AS + TYPE naturaln IS TABLE OF natural; + tb naturaln; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END pkg1; +/ +CREATE OR REPLACE PACKAGE BODY pkg1 AS + FUNCTION func1(a simple_integer) RETURN simple_integer IS + DECLARE + b x.y.z.s.t; + BEGIN + a := a + 1; + tb(1) := a; + raise info 'tb(1): %', tb(1); + RETURN a; + END func1; +END pkg1; +/ +ERROR: improper qualified name (too many dotted names): x.y.z.s.t +LINE 2: b x.y.z.s.t; + ^ +QUERY: DECLARE + b x.y.z.s.t; + BEGIN + a := a + 1; + tb(1) := a; + raise info 'tb(1): %', tb(1); + RETURN a; + END +SELECT 1::positiven; + positiven +----------- + 1 +(1 row) + +DROP FUNCTION func1; +ERROR: function func1 does not exist +DROP PROCEDURE proc1; +ERROR: function proc1 does not exist +DROP PACKAGE pkg1; +NOTICE: drop cascades to function public.func1(simple_integer) +-- cast +DECLARE + a natural := 5; + b naturaln := 4; + c positive := 3; + d positiven := 2; + e signtype := 1; + f simple_integer := 0; + g integer := 7; +BEGIN + a := b; + b := c; + c := d; + d := e; + e := f; + f := g; + g := a; + raise info 'a: %, b: %, c: %, d: %, e: %, f: %, g: %', + a, b, c, d, e, f, g; +END; +/ +INFO: a: 4, b: 3, c: 2, d: 1, e: 0, f: 7, g: 4 +DECLARE + a simple_integer := 2.3; + b simple_integer := true; + c simple_integer := '5'; + d simple_integer := cast('7' as simple_integer); +BEGIN + raise info 'a: %, b: %, c: %, d: %', + a, b, c, d; +END; +/ +INFO: a: 2, b: 1, c: 5, d: 7 +\c postgres +DROP DATABASE test_predefined_pltype; diff --git a/src/test/regress/expected/single_node_type_sanity.out b/src/test/regress/expected/single_node_type_sanity.out index 6ebaa61c1d33b73664ca2509489c2afddec0cd5d..13f6eae305f5cd13d749b00386f04260de07476e 100644 --- a/src/test/regress/expected/single_node_type_sanity.out +++ b/src/test/regress/expected/single_node_type_sanity.out @@ -93,10 +93,16 @@ SELECT p1.oid, p1.typname as basetype, p2.typname as arraytype, FROM pg_type p1 LEFT JOIN pg_type p2 ON (p1.typarray = p2.oid) WHERE p1.typarray <> 0 AND (p2.oid IS NULL OR p2.typelem <> p1.oid OR p2.typlen <> -1); - oid | basetype | arraytype | typelem | typlen ------+------------------+------------+---------+-------- - 32 | oidvector_extend | _oidvector | 30 | -1 -(1 row) + oid | basetype | arraytype | typelem | typlen +-------+------------------+------------+---------+-------- + 32 | oidvector_extend | _oidvector | 30 | -1 +--? natural.* +--? naturaln.* +--? positive.* +--? positiven.* +--? signtype.* +--? simple_integer.* +(7 rows) -- Look for range types that do not have a pg_range entry SELECT p1.oid, p1.typname diff --git a/src/test/regress/parallel_schedule0 b/src/test/regress/parallel_schedule0 index 54db9d894a9decd245fecad407337e8434f6b089..f10155ace339f70cc73f9cbb8af08f92db094941 100644 --- a/src/test/regress/parallel_schedule0 +++ b/src/test/regress/parallel_schedule0 @@ -786,7 +786,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 plpgsql_predefined_types #test: plpgsql_nest_compile test: arrayinterface_ted test: function_default_test plpgsql_inout_param record_slow_sql_in_proc diff --git a/src/test/regress/parallel_schedule0B b/src/test/regress/parallel_schedule0B index 7fde7aabc925d66fccb08b21d68a56551ec172ec..bff1dcc46a277037c3e34538a3b5b1de7c37d4f6 100644 --- a/src/test/regress/parallel_schedule0B +++ b/src/test/regress/parallel_schedule0B @@ -281,7 +281,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 plpgsql_predefined_types #test: plpgsql_nest_compile test: arrayinterface_ted test: function_default_test plpgsql_inout_param diff --git a/src/test/regress/sql/plpgsql_predefined_types.sql b/src/test/regress/sql/plpgsql_predefined_types.sql new file mode 100644 index 0000000000000000000000000000000000000000..9bcd577b1dbca842fe1ae5698df90f4728c50dec --- /dev/null +++ b/src/test/regress/sql/plpgsql_predefined_types.sql @@ -0,0 +1,660 @@ +CREATE DATABASE test_predefined_pltype; +\c test_predefined_pltype; + +-- natural +DECLARE + m natural := 1; + n natural := 2; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +-- invalid value +DECLARE + m natural := -1; + n natural := 2; +BEGIN + m := m - n; + raise info 'm: %', m; +END; +/ + +-- Result of such kind of testcases is wrong by now. +-- An error is expected when assigning -3 to n during typecast. +-- Wait until the bug is fixed to correct it. +DECLARE + m text := '-3'; + n natural := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +-- overflow +DECLARE + m natural := 1; + n natural := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m natural := 0; + n natural := 2147483647; +BEGIN + m := m - n - 2; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := 2147483649; + n natural := 0; +BEGIN + n := m; +END; +/ + +DECLARE + m NUMBER(18) := -2147483649; + n natural := 0; +BEGIN + n := m; +END; +/ + +-- naturaln +DECLARE + m naturaln := 1; + n naturaln := 2; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +-- invalid value +DECLARE + m naturaln := -1; + n naturaln := 2; +BEGIN + m := m - n; + raise info 'm: %', m; +END; +/ + +DECLARE + m naturaln := NULL; + n naturaln := 2; +BEGIN + m := m - n; + raise info 'm: %', m; +END; +/ + +DECLARE + m float := -3.2; + n naturaln := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +DECLARE + m float := NULL; + n naturaln := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +-- overflow +DECLARE + m naturaln := 1; + n naturaln := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m naturaln := 0; + n naturaln := 2147483647; +BEGIN + m := m - n - 2; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := 2147483649; + n naturaln := 0; +BEGIN + n := m; +END; +/ + +DECLARE + m NUMBER(18) := -2147483649; + n naturaln := 0; +BEGIN + n := m; +END; +/ + + +-- positive +DECLARE + m positive := 5; + n positive := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +-- invalid value +DECLARE + m positive := 0; + n positive := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := -3; + n positive := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +-- overflow +DECLARE + m positive := 1; + n positive := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m positive := 1; + n positive := 2147483647; +BEGIN + m := m - n - 3; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := 2147483648; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +DECLARE + m NUMBER(18) := -2147483649; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +-- positiven +DECLARE + m positiven := 5; + n positiven := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +-- invalid value +DECLARE + m positiven := 0; + n positiven := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m positiven := NULL; + n positiven := 6; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := -3; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +DECLARE + m text := NULL; + n positiven := 1; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +-- overflow +DECLARE + m positiven := 1; + n positiven := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m positiven := 1; + n positiven := 2147483647; +BEGIN + m := m - n - 3; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := 2147483648; + n positiven := 1; +BEGIN + n := m; +END; +/ + +DECLARE + m NUMBER(18) := -2147483649; + n positiven := 1; +BEGIN + n := m; +END; +/ + +-- signtype +DECLARE + x signtype := 0; + y signtype := 1; + z signtype := -1; +BEGIN + z := x + y + z; + raise info 'm: %', z; +END; +/ + +-- invalid value +DECLARE + x signtype := 0; + y signtype := 1; + z signtype := -1; +BEGIN + z := x + y - z; + raise info 'm: %', z; +END; +/ + +DECLARE + m text := '2'; + n signtype := 0; +BEGIN + n := m; + raise info 'n: %', n; +END; +/ + +-- simple_integer +DECLARE + m simple_integer := -9; + n simple_integer := 10; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +-- invalid value +DECLARE + m simple_integer := NULL; + n simple_integer := 10; +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := 0; + n SIMPLE_INTEGER := 0; +BEGIN + m := NULL; + n := m; +END; +/ + +-- overflow +DECLARE + m simple_integer := 1; + n simple_integer := 2147483648; -- ERROR +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m simple_integer := 1; + n simple_integer := -2147483649; -- ERROR +BEGIN + m := m + n; + raise info 'm: %', m; +END; +/ + +DECLARE + m simple_integer := 2; + n simple_integer := 2147483647; +BEGIN + m := m + n; + raise info 'm: %', m; -- -2147483647 +END; +/ + +DECLARE + m simple_integer := 2147483647; + n simple_integer := 2147483647; +BEGIN + m := m * n; + raise info 'm: %', m; -- 1 +END; +/ + +DECLARE + m simple_integer := -2; + n simple_integer := 2147483647; +BEGIN + m := m - n; + raise info 'm: %', m; -- 2147483647 +END; +/ + +DECLARE + m simple_integer := -2; + n simple_integer := 2147483647; +BEGIN + m := n / m; + raise info 'm: %', m; -- -1073741824 +END; +/ + +DECLARE + m simple_integer := -1; + n simple_integer := -2147483648; +BEGIN + m := n / m; + raise info 'm: %', m; -- ERROR +END; +/ + +DECLARE + m simple_integer := -2; + n simple_integer := 2147483647; +BEGIN + m := n % m; + raise info 'm: %', m; +END; +/ + +DECLARE + m NUMBER(18) := 0; + n SIMPLE_INTEGER := 0; +BEGIN + m := -2147483649; + n := m; +END; +/ + +DECLARE + m NUMBER(18) := 0; + n SIMPLE_INTEGER := 0; +BEGIN + m := 2147483649; + n := m; +END; +/ + +-- scope of effect +DROP TYPE IF EXISTS simple_integer; -- ERROR +ALTER DOMAIN positiven DROP NOT NULL; -- ERROR +SELECT oid, typname FROM pg_type WHERE typname='simple_integer' ORDER BY oid ASC; +SELECT 1::simple_integer; -- ERROR +CREATE TYPE simple_integer AS (a int, b varchar(10)); +SELECT oid, typname FROM pg_type WHERE typname='simple_integer'; +SELECT (1, 'a')::simple_integer; +SELECT (1, 'a')::simple_integer + (2, 'b')::simple_integer; -- ERROR +DECLARE + m simple_integer; +BEGIN + m.a := 1; -- ERROR + m.b := 'a'; +END; +/ +DROP TYPE simple_integer; +SELECT oid, typname FROM pg_type WHERE typname='simple_integer'; + +CREATE DOMAIN positiven as varchar(10); +SELECT 'test'::positiven; +DECLARE + m positiven := 1; + n positiven := 'a'; -- ERROR +BEGIN + m := 2; + n := 'b'; + raise info 'm: %, n: %', m, n; +END; +/ + +DECLARE + m positive := 1; + TYPE positive IS varray(5) of natural; + arr positive; +BEGIN + m := 2; + arr(1) := 1; + raise info 'm: %, arr(1): %', m, arr(1); +END; +/ + +DECLARE + m naturaln := 1; + SUBTYPE naturaln IS INTEGER; + n naturaln := -2; +BEGIN + m := 2; + n := -5; + raise info 'm: %, n: %', m, n; +END; +/ + +CREATE OR REPLACE FUNCTION func1(a positiven) RETURNS positiven AS +$$ +BEGIN + a := a + 1; + RETURN a; +END +$$ +LANGUAGE 'plpgsql'; +SELECT func1(3); +SELECT func1(0); -- ERROR +SELECT func1(NULL); -- ERROR + +DROP FUNCTION IF EXISTS func2; +ALTER FUNCTION func1(positiven) RENAME TO func2; +SELECT func1(3); +SELECT func2(3); + +CREATE OR REPLACE PROCEDURE proc1(a signtype) AS +BEGIN + a := -a; + raise info 'a: %', a; +END; +/ +CALL proc1(1); +CALL proc1(2); -- ERROR + +DROP SCHEMA IF EXISTS schem1; +CREATE SCHEMA schem1; +ALTER PROCEDURE proc1(signtype) SET SCHEMA schem1; +CALL proc1(1); +CALL schem1.proc1(1); + +DROP FUNCTION func2(positiven); +DROP PROCEDURE schem1.proc1(signtype); +DROP SCHEMA schem1; + +CREATE OR REPLACE PACKAGE pkg1 AS + TYPE naturaln IS TABLE OF natural; + tb naturaln; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END pkg1; +/ + +CREATE OR REPLACE PACKAGE BODY pkg1 AS + FUNCTION func1(a simple_integer) RETURN simple_integer IS + BEGIN + a := a + 1; + tb(1) := a; + raise info 'tb(1): %', tb(1); + RETURN a; + END func1; +END pkg1; +/ +SELECT pkg1.func1(-3); + +DROP PACKAGE pkg1; + +-- recover after exception +DECLARE + a natural := 1; + b x.y.z.s.t := 1; +BEGIN + a := 2; +END; +/ +SELECT 2::natural; + +CREATE OR REPLACE FUNCTION func1(a positiven) RETURNS x.y.z.s.t AS +$$ +BEGIN + a := a + 1; + RETURN a; +END +$$ +LANGUAGE 'plpgsql'; + +SELECT 2::positive; + +CREATE OR REPLACE PROCEDURE proc1(a signtype, b x.y.z.s.t) AS +BEGIN + a := -a; + raise info 'a: %', a; +END; +/ +SELECT 2::simple_integer; + +CREATE OR REPLACE PACKAGE pkg1 AS + TYPE naturaln IS TABLE OF natural; + tb naturaln; + ab x.y.z.s.t; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END pkg1; +/ +SELECT 1::signtype; + +CREATE OR REPLACE PACKAGE pkg1 AS + TYPE naturaln IS TABLE OF natural; + tb naturaln; + FUNCTION func1(a simple_integer) RETURN simple_integer; +END pkg1; +/ + +CREATE OR REPLACE PACKAGE BODY pkg1 AS + FUNCTION func1(a simple_integer) RETURN simple_integer IS + DECLARE + b x.y.z.s.t; + BEGIN + a := a + 1; + tb(1) := a; + raise info 'tb(1): %', tb(1); + RETURN a; + END func1; +END pkg1; +/ + +SELECT 1::positiven; + +DROP FUNCTION func1; +DROP PROCEDURE proc1; +DROP PACKAGE pkg1; +-- cast +DECLARE + a natural := 5; + b naturaln := 4; + c positive := 3; + d positiven := 2; + e signtype := 1; + f simple_integer := 0; + g integer := 7; +BEGIN + a := b; + b := c; + c := d; + d := e; + e := f; + f := g; + g := a; + raise info 'a: %, b: %, c: %, d: %, e: %, f: %, g: %', + a, b, c, d, e, f, g; +END; +/ + +DECLARE + a simple_integer := 2.3; + b simple_integer := true; + c simple_integer := '5'; + d simple_integer := cast('7' as simple_integer); +BEGIN + raise info 'a: %, b: %, c: %, d: %', + a, b, c, d; +END; +/ + +\c postgres +DROP DATABASE test_predefined_pltype; \ No newline at end of file