!5701 完善PL中的type、recor:包外使用包类型并继承默认值
Merge pull request !5701 from 雷紫薇/req129584_2_const
This commit is contained in:
@ -12777,10 +12777,11 @@ parse_datatype(const char *string, int location)
|
||||
{
|
||||
Oid type_id;
|
||||
int32 typmod;
|
||||
int expr_len = 0;
|
||||
sql_error_callback_arg cbarg;
|
||||
ErrorContextCallback syntax_errcontext;
|
||||
MemoryContext oldCxt = NULL;
|
||||
|
||||
PLpgSQL_type* datatype = NULL;
|
||||
cbarg.location = location;
|
||||
cbarg.leaderlen = 0;
|
||||
|
||||
@ -12827,11 +12828,13 @@ parse_datatype(const char *string, int location)
|
||||
/* Okay, build a PLpgSQL_type data structure for it */
|
||||
if (u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile == NULL)
|
||||
{
|
||||
return plpgsql_build_datatype(type_id, typmod, 0, typeDependExtend);
|
||||
}
|
||||
|
||||
return plpgsql_build_datatype(type_id, typmod,
|
||||
datatype = plpgsql_build_datatype(type_id, typmod, 0, typeDependExtend);
|
||||
} else {
|
||||
datatype = plpgsql_build_datatype(type_id, typmod,
|
||||
u_sess->plsql_cxt.curr_compile_context->plpgsql_curr_compile->fn_input_collation, typeDependExtend);
|
||||
}
|
||||
datatype->defaultvalues = get_default_plpgsql_expr_from_typeoid(type_id, &expr_len);
|
||||
return datatype;
|
||||
}
|
||||
|
||||
/* Build a arrary_type by elem_type. */
|
||||
@ -13546,7 +13549,7 @@ static Node* make_columnDef_from_attr(PLpgSQL_rec_attr* attr)
|
||||
n->is_not_null = false;
|
||||
n->is_from_type = false;
|
||||
n->storage = 0;
|
||||
n->raw_default = NULL;
|
||||
n->raw_default = attr->defaultvalue ? get_default_node_from_plpgsql_expr(attr->defaultvalue) : NULL;
|
||||
n->cooked_default = NULL;
|
||||
n->collClause = NULL;
|
||||
n->clientLogicColumnRef=NULL;
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "catalog/gs_package.h"
|
||||
#include "catalog/gs_package_fn.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "catalog/pg_attrdef.h"
|
||||
#include "commands/sqladvisor.h"
|
||||
#include "executor/spi.h"
|
||||
#include "funcapi.h"
|
||||
@ -90,7 +91,7 @@ static Node* plpgsql_post_column_ref(ParseState* pstate, ColumnRef* cref, Node*
|
||||
static Node* plpgsql_param_ref(ParseState* pstate, ParamRef* pref);
|
||||
static Node* resolve_column_ref(ParseState* pstate, PLpgSQL_expr* expr, ColumnRef* cref, bool error_if_no_field);
|
||||
static Node* make_datum_param(PLpgSQL_expr* expr, int dno, int location);
|
||||
extern PLpgSQL_row* build_row_from_class(Oid class_oid);
|
||||
extern PLpgSQL_row* build_row_from_class(Oid class_oid, PLpgSQL_expr** defaultvalues);
|
||||
static PLpgSQL_row* build_row_from_vars(PLpgSQL_variable** vars, int numvars);
|
||||
static void compute_function_hashkey(HeapTuple proc_tup, FunctionCallInfo fcinfo, Form_pg_proc proc_struct,
|
||||
PLpgSQL_func_hashkey* hashkey, bool for_validator);
|
||||
@ -675,6 +676,28 @@ static bool CheckPipelinedResIsTuple(Form_pg_type type_struct) {
|
||||
return pipelinedResIsTuple;
|
||||
}
|
||||
|
||||
static void plpgsql_add_param_initdatums(int *newvarnos, int newnum, int** oldvarnos, int oldnum)
|
||||
{
|
||||
int i;
|
||||
int n = 0;
|
||||
int *varnos = NULL;
|
||||
errno_t rc = 0;
|
||||
varnos = (int*)palloc(sizeof(int) * (newnum + oldnum));
|
||||
|
||||
if (oldnum > 0) {
|
||||
rc = memcpy_s(varnos, sizeof(int) * oldnum, (int*)(*oldvarnos), sizeof(int) * oldnum);
|
||||
securec_check(rc, "", "");
|
||||
}
|
||||
if (newnum > 0) {
|
||||
rc = memcpy_s(varnos + oldnum, sizeof(int) * newnum, newvarnos, sizeof(int) * newnum);
|
||||
securec_check(rc, "", "");
|
||||
}
|
||||
|
||||
if (*oldvarnos)
|
||||
pfree(*oldvarnos);
|
||||
*oldvarnos = varnos;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the slow part of plpgsql_compile().
|
||||
*
|
||||
@ -723,7 +746,8 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
||||
PLpgSQL_variable** out_arg_variables;
|
||||
Oid pkgoid = InvalidOid;
|
||||
Oid namespaceOid = InvalidOid;
|
||||
|
||||
int *allvarnos = NULL;
|
||||
int n_varnos = 0;
|
||||
Oid* saved_pseudo_current_userId = NULL;
|
||||
char* signature = NULL;
|
||||
|
||||
@ -1006,6 +1030,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
||||
const int buf_size = 32;
|
||||
char buf[buf_size];
|
||||
Oid arg_type_id = arg_types[i];
|
||||
int attrnum = 0;
|
||||
char arg_mode = arg_modes ? arg_modes[i] : PROARGMODE_IN;
|
||||
PLpgSQL_variable* argvariable = NULL;
|
||||
int arg_item_type;
|
||||
@ -1020,6 +1045,9 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
||||
|
||||
/* Create datatype info */
|
||||
PLpgSQL_type* argdtype = plpgsql_build_datatype(arg_type_id, -1, func->fn_input_collation);
|
||||
if (arg_mode != PROARGMODE_IN && arg_mode != PROARGMODE_INOUT) {
|
||||
argdtype->defaultvalues = get_default_plpgsql_expr_from_typeoid(arg_type_id, &attrnum);
|
||||
}
|
||||
|
||||
/* Disallow pseudotype argument */
|
||||
/* (note we already replaced polymorphic types) */
|
||||
@ -1034,6 +1062,11 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
||||
} else {
|
||||
argvariable = plpgsql_build_variable(buf, 0, argdtype, false);
|
||||
}
|
||||
if (argdtype->defaultvalues) {
|
||||
PLpgSQL_row *row = (PLpgSQL_row *)argvariable;
|
||||
plpgsql_add_param_initdatums(row->varnos, attrnum, &allvarnos, n_varnos);
|
||||
n_varnos = n_varnos + attrnum;
|
||||
}
|
||||
|
||||
if (argvariable->dtype == PLPGSQL_DTYPE_VAR) {
|
||||
arg_item_type = PLPGSQL_NSTYPE_VAR;
|
||||
@ -1421,6 +1454,10 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup,
|
||||
errmsg("Syntax parsing error, plpgsql parser returned %d", parse_rc)));
|
||||
}
|
||||
func->action = curr_compile->plpgsql_parse_result;
|
||||
if (n_varnos > 0) {
|
||||
plpgsql_add_param_initdatums(allvarnos, n_varnos, &func->action->initvarnos, func->action->n_initvars);
|
||||
func->action->n_initvars = func->action->n_initvars + n_varnos;
|
||||
}
|
||||
|
||||
if (is_dml_trigger && func->action->isAutonomous) {
|
||||
ereport(ERROR,
|
||||
@ -3929,7 +3966,7 @@ PLpgSQL_variable* plpgsql_build_variable(const char* refname, int lineno, PLpgSQ
|
||||
/* Composite type -- build a row variable */
|
||||
PLpgSQL_row* row = NULL;
|
||||
|
||||
row = build_row_from_class(dtype->typrelid);
|
||||
row = build_row_from_class(dtype->typrelid, dtype->defaultvalues);
|
||||
row->addNamespace = add2namespace;
|
||||
row->customErrorCode = 0;
|
||||
if (0 == strcmp(format_type_be(row->rowtupdesc->tdtypeid), "exception")) {
|
||||
@ -4313,7 +4350,7 @@ void plpgsql_build_synonym(char* typname, char* basetypname)
|
||||
/*
|
||||
* Build a row-variable data structure given the pg_class OID.
|
||||
*/
|
||||
PLpgSQL_row* build_row_from_class(Oid class_oid)
|
||||
PLpgSQL_row* build_row_from_class(Oid class_oid, PLpgSQL_expr** defaultvalues)
|
||||
{
|
||||
/*
|
||||
* Open the relation to get info.
|
||||
@ -4374,6 +4411,8 @@ PLpgSQL_row* build_row_from_class(Oid class_oid)
|
||||
*/
|
||||
var = plpgsql_build_variable(refname, 0, plpgsql_build_datatype(attr_struct->atttypid,
|
||||
attr_struct->atttypmod, attr_struct->attcollation), false);
|
||||
if (defaultvalues != NULL)
|
||||
((PLpgSQL_var*)var)->default_val = defaultvalues[i];
|
||||
|
||||
/* Add the variable to the row */
|
||||
row->fieldnames[i] = attname;
|
||||
@ -4637,7 +4676,7 @@ PLpgSQL_type* build_datatype(HeapTuple type_tup, int32 typmod, Oid collation)
|
||||
errmsg("type \"%s\" is only a shell when build data type in PLSQL.", NameStr(type_struct->typname))));
|
||||
}
|
||||
PLpgSQL_type* typ = (PLpgSQL_type*)palloc(sizeof(PLpgSQL_type));
|
||||
|
||||
typ->defaultvalues = NULL;
|
||||
typ->typname = pstrdup(NameStr(type_struct->typname));
|
||||
typ->typoid = HeapTupleGetOid(type_tup);
|
||||
typ->collectionType = PLPGSQL_COLLECTION_NONE;
|
||||
@ -5947,3 +5986,106 @@ void checkArrayTypeInsert(ParseState* pstate, Expr* expr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Node* get_default_node_from_plpgsql_expr(PLpgSQL_expr *expr)
|
||||
{
|
||||
MemoryContext cur = CurrentMemoryContext;
|
||||
MemoryContext temp = NULL;
|
||||
CachedPlanSource* plansource = NULL;
|
||||
SelectStmt* stmt = NULL;
|
||||
Value *val = NULL;
|
||||
_SPI_plan plan;
|
||||
parse_query_func parser = GetRawParser();
|
||||
|
||||
if (expr->query == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SPI_STACK_LOG("connect", NULL, NULL);
|
||||
if (SPI_connect() != SPI_OK_CONNECT) {
|
||||
ereport(ERROR, (errcode(ERRCODE_SPI_CONNECTION_FAILURE), errmsg("SPI_connect failed")));
|
||||
}
|
||||
SPI_STACK_LOG("begin", expr->query, NULL);
|
||||
if (_SPI_begin_call(true) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rc = memset_s(&plan, sizeof(_SPI_plan), '\0', sizeof(_SPI_plan));
|
||||
securec_check_c(rc, "\0", "\0");
|
||||
plan.magic = _SPI_PLAN_MAGIC;
|
||||
plan.cursor_options = 0;
|
||||
plan.spi_key = INVALID_SPI_KEY;
|
||||
|
||||
_SPI_prepare_oneshot_plan(expr->query, &plan, parser);
|
||||
plansource = (CachedPlanSource*)lfirst(plan.plancache_list->head);
|
||||
stmt = (SelectStmt*)plansource->raw_parse_tree;
|
||||
if (stmt->targetList) {
|
||||
Node* node = (Node*)lfirst(stmt->targetList->head);
|
||||
if (IsA(node, ResTarget)) {
|
||||
ResTarget* resTarget = (ResTarget*)node;
|
||||
temp = MemoryContextSwitchTo(cur);
|
||||
val = (Value*)copyObject((void*)resTarget->val);
|
||||
temp = MemoryContextSwitchTo(temp);
|
||||
}
|
||||
}
|
||||
|
||||
if (_SPI_end_call(true) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
SPI_STACK_LOG("finish", NULL, NULL);
|
||||
if (SPI_finish() != SPI_OK_FINISH) {
|
||||
ereport(ERROR, (errcode(ERRCODE_SPI_FINISH_FAILURE), errmsg("SPI_finish failed")));
|
||||
}
|
||||
return (Node*)val;
|
||||
}
|
||||
|
||||
PLpgSQL_expr** get_default_plpgsql_expr_from_typeoid(Oid typeOid, int* attrnum)
|
||||
{
|
||||
PLpgSQL_expr** defaultvalues = NULL;
|
||||
ScanKeyData skey;
|
||||
HeapTuple htup;
|
||||
bool isnull = false;
|
||||
Datum typrelid = typeidTypeRelid(typeOid);
|
||||
if (typrelid != InvalidOid) {
|
||||
ScanKeyInit(&skey, Anum_pg_attrdef_adrelid, BTEqualStrategyNumber, F_OIDEQ, typrelid);
|
||||
Relation adrel = heap_open(AttrDefaultRelationId, AccessShareLock);
|
||||
SysScanDesc adscan = systable_beginscan(adrel, AttrDefaultIndexId, true, NULL, 1, &skey);
|
||||
List* del_list = NIL;
|
||||
ListCell *lc = NULL;
|
||||
int i = 0, j = 0;
|
||||
while (HeapTupleIsValid(htup = systable_getnext(adscan))) {
|
||||
Form_pg_attrdef adform = (Form_pg_attrdef)GETSTRUCT(htup);
|
||||
Datum val;
|
||||
StringInfoData ds;
|
||||
val = fastgetattr(htup, Anum_pg_attrdef_adsrc, adrel->rd_att, &isnull);
|
||||
char *adsrc_str = isnull ? NULL : TextDatumGetCString(val);
|
||||
initStringInfo(&ds);
|
||||
appendStringInfoString(&ds, "SELECT ");
|
||||
appendStringInfoString(&ds, adsrc_str);
|
||||
del_list = lappend(del_list, ds.data);
|
||||
j++;
|
||||
}
|
||||
*attrnum = j;
|
||||
if (j > 0) {
|
||||
defaultvalues = (PLpgSQL_expr **)palloc0(sizeof(PLpgSQL_expr *) * j);
|
||||
PLpgSQL_expr *exprs = (PLpgSQL_expr *)palloc0(sizeof(PLpgSQL_expr) * j);
|
||||
foreach (lc, del_list) {
|
||||
char *query = (char *)lfirst(lc);
|
||||
PLpgSQL_expr *expr = exprs + i;
|
||||
expr->dtype = PLPGSQL_DTYPE_EXPR;
|
||||
expr->query = pstrdup(query);
|
||||
expr->plan = NULL;
|
||||
expr->paramnos = NULL;
|
||||
expr->isouttype = false;
|
||||
expr->idx = UINT32_MAX;
|
||||
expr->out_param_dno = -1;
|
||||
expr->is_have_tableof_index_func = true;
|
||||
defaultvalues[i] = expr;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
systable_endscan(adscan);
|
||||
heap_close(adrel, AccessShareLock);
|
||||
}
|
||||
return defaultvalues;
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ extern Oid findPackageParameter(const char* objname);
|
||||
|
||||
extern int plpgsql_getCustomErrorCode(void);
|
||||
|
||||
extern PLpgSQL_row* build_row_from_class(Oid class_oid);
|
||||
extern PLpgSQL_row* build_row_from_class(Oid class_oid, PLpgSQL_expr** defaultvalues);
|
||||
|
||||
extern int GetLineNumber(const char* procedureStr, int loc);
|
||||
|
||||
|
||||
@ -489,6 +489,7 @@ typedef struct { /* openGauss data type */
|
||||
PLpgSQL_expr* cursorExpr;
|
||||
int cursorDno;
|
||||
char typtyp;
|
||||
PLpgSQL_expr** defaultvalues;
|
||||
} PLpgSQL_type;
|
||||
|
||||
typedef struct {
|
||||
@ -1858,6 +1859,8 @@ extern PLpgSQL_datum* plpgsql_lookup_datum(
|
||||
extern PLpgSQL_type* plpgsql_get_row_field_type(int dno, const char* fieldname, MemoryContext old_cxt);
|
||||
extern PLpgSQL_resolve_option GetResolveOption();
|
||||
extern Node* plpgsql_check_match_var(Node* node, ParseState* pstate, ColumnRef* cref);
|
||||
extern Node* get_default_node_from_plpgsql_expr(PLpgSQL_expr *expr);
|
||||
extern PLpgSQL_expr** get_default_plpgsql_expr_from_typeoid(Oid typeOid, int* attrnum);
|
||||
|
||||
/* ----------
|
||||
* Functions in pl_handler.c
|
||||
|
||||
446
src/test/regress/expected/plpgsql_default_value_various_type.out
Normal file
446
src/test/regress/expected/plpgsql_default_value_various_type.out
Normal file
@ -0,0 +1,446 @@
|
||||
create schema test_pkg_default_value;
|
||||
set current_schema = test_pkg_default_value;
|
||||
-- test default expr
|
||||
CREATE FUNCTION func1(num2 inout int,num3 inout int) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 9 + num3;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
CREATE OR REPLACE FUNCTION func3(num2 inout int) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 2;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
CREATE FUNCTION func2(num1 inout int, st1 inout varchar(10), num2 inout int) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 9;
|
||||
raise info 'str1 is %', NVL(str1,'NULL');
|
||||
raise info 'str2 is %', NVL(str2,'NULL');
|
||||
raise info 'num1 is %', num1;
|
||||
raise info 'num2 is %', num2;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
CREATE FUNCTION func4(num2 inout int,num3 inout bool) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 1;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (+1));
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
adsrc
|
||||
-------
|
||||
(+ 1)
|
||||
(1 row)
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is 1
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := 1+-9+8*(-7)+1*-2);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
adsrc
|
||||
------------------------------------------
|
||||
(((1 + (-9)) + (8 * (-7))) + (1 * (-2)))
|
||||
(1 row)
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is -66
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := 1+-9+8/-11*(-7)+1*-2*2/5);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
adsrc
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
((((1 + (-9)))::double precision + ((8 / (-11)) * ((-7))::double precision)) + (((1 * (-2)) * 2) / 5))
|
||||
(1 row)
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is -4
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := 8*-11*(-7)+1*-2*2/5+9);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
adsrc
|
||||
-----------------------------------------------------------------------------------------------
|
||||
(((((8 * (-11)) * (-7)))::double precision + (((1 * (-2)) * 2) / 5)) + (9)::double precision)
|
||||
(1 row)
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is 624
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := -1);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
adsrc
|
||||
-------
|
||||
(-1)
|
||||
(1 row)
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is -1
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f VARCHAR2(5) := 'abus');
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
adsrc
|
||||
---------------------------
|
||||
'abus'::character varying
|
||||
(1 row)
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', NVL(r1.f,'NULL');
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is abus
|
||||
-- test expr error
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (1+));
|
||||
END r_types;
|
||||
/
|
||||
ERROR: syntax error at or near ")"
|
||||
LINE 1: SELECT (1+)
|
||||
^
|
||||
QUERY: SELECT (1+)
|
||||
CONTEXT: compilation of PL/pgSQL package near line 1
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := +);
|
||||
END r_types;
|
||||
/
|
||||
ERROR: syntax error at end of input
|
||||
LINE 1: SELECT +
|
||||
^
|
||||
QUERY: SELECT +
|
||||
CONTEXT: compilation of PL/pgSQL package near line 1
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (+));
|
||||
END r_types;
|
||||
/
|
||||
ERROR: syntax error at or near "(+)"
|
||||
LINE 1: SELECT (+)
|
||||
^
|
||||
QUERY: SELECT (+)
|
||||
CONTEXT: compilation of PL/pgSQL package near line 1
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (a+b));
|
||||
END r_types;
|
||||
/
|
||||
ERROR: column "a" does not exist
|
||||
CONTEXT: compilation of PL/pgSQL package near line 1
|
||||
-- normal default
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f VARCHAR2(5) := 'abcde', f2 VARCHAR2(5) := 'waxtr');
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f VARCHAR2(5) := 'a1c2e', f2 VARCHAR2(5) := 'w5x3r');
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', NVL(r1.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r1.f2,'NULL');
|
||||
raise info 'r2.f is %', NVL(r2.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r2.f2,'NULL');
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is abcde
|
||||
INFO: r1.f2 is waxtr
|
||||
INFO: r2.f is a1c2e
|
||||
INFO: r1.f2 is w5x3r
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f date := '2001-9-28', f2 timestamp := '1957-06-13');
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f date := '2000-7-28', f2 timestamp := '1987-06-03');
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is Fri Sep 28 00:00:00 2001
|
||||
INFO: r1.f2 is Thu Jun 13 00:00:00 1957
|
||||
INFO: r1.f is Fri Jul 28 00:00:00 2000
|
||||
INFO: r1.f2 is Wed Jun 03 00:00:00 1987
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f boolean := true, f2 numeric := 19.578);
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f boolean := false, f2 numeric := 13.278);
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is t
|
||||
INFO: r1.f2 is 19.578
|
||||
INFO: r1.f is f
|
||||
INFO: r1.f2 is 13.278
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f money := 10.5, f2 int := 15);
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f money := 9.6, f2 int := 13);
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is $10.50
|
||||
INFO: r1.f2 is 15
|
||||
INFO: r1.f is $9.60
|
||||
INFO: r1.f2 is 13
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f integer := 10, f2 oid := 15);
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f integer := 9, f2 oid := 13);
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is 10
|
||||
INFO: r1.f2 is 15
|
||||
INFO: r1.f is 9
|
||||
INFO: r1.f2 is 13
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f name := 'abcde', f2 text := 'waxtr');
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f name := 'a1c2e', f2 text := 'w5x3r');
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', NVL(r1.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r1.f2,'NULL');
|
||||
raise info 'r2.f is %', NVL(r2.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r2.f2,'NULL');
|
||||
END;
|
||||
/
|
||||
INFO: r1.f is abcde
|
||||
INFO: r1.f2 is waxtr
|
||||
INFO: r2.f is a1c2e
|
||||
INFO: r1.f2 is w5x3r
|
||||
-- pkg param default
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f VARCHAR2(5) := 'abcde', f2 VARCHAR2(5) := 'syutw');
|
||||
TYPE r_type_2 IS RECORD (f VARCHAR2(5));
|
||||
END r_types;
|
||||
/
|
||||
CREATE OR REPLACE PROCEDURE p1 (
|
||||
x OUT r_types.r_type_1,
|
||||
y OUT r_types.r_type_2,
|
||||
z OUT VARCHAR2)
|
||||
AUTHID CURRENT_USER IS
|
||||
BEGIN
|
||||
raise info 'x.f is %', NVL(x.f,'NULL');
|
||||
raise info 'x.f2 is %', NVL(x.f2,'NULL');
|
||||
raise info 'y.f is %', NVL(y.f,'NULL');
|
||||
raise info 'z is %', NVL(z,'NULL');
|
||||
END;
|
||||
/
|
||||
CREATE OR REPLACE PROCEDURE p2 (
|
||||
x IN r_types.r_type_1,
|
||||
y IN r_types.r_type_2,
|
||||
z IN VARCHAR2)
|
||||
AUTHID CURRENT_USER IS
|
||||
BEGIN
|
||||
raise info 'x.f is %', NVL(x.f,'NULL');
|
||||
raise info 'x.f2 is %', NVL(x.f2,'NULL');
|
||||
raise info 'y.f is %', NVL(y.f,'NULL');
|
||||
raise info 'z is %', NVL(z,'NULL');
|
||||
END;
|
||||
/
|
||||
CREATE OR REPLACE PROCEDURE p3 (
|
||||
x INOUT r_types.r_type_1,
|
||||
y INOUT r_types.r_type_2,
|
||||
z INOUT VARCHAR2)
|
||||
AUTHID CURRENT_USER IS
|
||||
BEGIN
|
||||
raise info 'x.f is %', NVL(x.f,'NULL');
|
||||
raise info 'x.f2 is %', NVL(x.f2,'NULL');
|
||||
raise info 'y.f is %', NVL(y.f,'NULL');
|
||||
raise info 'z is %', NVL(z,'NULL');
|
||||
END;
|
||||
/
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_types.r_type_2;
|
||||
s VARCHAR2(5) := 'fghij';
|
||||
BEGIN
|
||||
raise info '===============p1===================';
|
||||
p1 (r1, r2, s);
|
||||
raise info '===============p2===================';
|
||||
p2 (r1, r2, s);
|
||||
raise info '===============p3===================';
|
||||
p3 (r1, r2, s);
|
||||
r1.f:='waqrt';
|
||||
r1.f2:='bfgrf';
|
||||
r2.f:='nuytg';
|
||||
raise info '===============p1===================';
|
||||
p1 (r1, r2, s);
|
||||
raise info '===============p2===================';
|
||||
p2 (r1, r2, s);
|
||||
raise info '===============p3===================';
|
||||
p3 (r1, r2, s);
|
||||
END;
|
||||
/
|
||||
INFO: ===============p1===================
|
||||
INFO: x.f is abcde
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 6 at SQL statement
|
||||
INFO: x.f2 is syutw
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 6 at SQL statement
|
||||
INFO: y.f is NULL
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 6 at SQL statement
|
||||
INFO: z is NULL
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 6 at SQL statement
|
||||
INFO: ===============p2===================
|
||||
INFO: x.f is abcde
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 8 at PERFORM
|
||||
INFO: x.f2 is syutw
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 8 at PERFORM
|
||||
INFO: y.f is NULL
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 8 at PERFORM
|
||||
INFO: z is NULL
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 8 at PERFORM
|
||||
INFO: ===============p3===================
|
||||
INFO: x.f is abcde
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 10 at SQL statement
|
||||
INFO: x.f2 is syutw
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 10 at SQL statement
|
||||
INFO: y.f is NULL
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 10 at SQL statement
|
||||
INFO: z is NULL
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 10 at SQL statement
|
||||
INFO: ===============p1===================
|
||||
INFO: x.f is abcde
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 15 at SQL statement
|
||||
INFO: x.f2 is syutw
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 15 at SQL statement
|
||||
INFO: y.f is NULL
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 15 at SQL statement
|
||||
INFO: z is NULL
|
||||
CONTEXT: SQL statement "CALL p1(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 15 at SQL statement
|
||||
INFO: ===============p2===================
|
||||
INFO: x.f is abcde
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 17 at PERFORM
|
||||
INFO: x.f2 is syutw
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 17 at PERFORM
|
||||
INFO: y.f is NULL
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 17 at PERFORM
|
||||
INFO: z is NULL
|
||||
CONTEXT: SQL statement "CALL p2(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 17 at PERFORM
|
||||
INFO: ===============p3===================
|
||||
INFO: x.f is abcde
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 19 at SQL statement
|
||||
INFO: x.f2 is syutw
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 19 at SQL statement
|
||||
INFO: y.f is NULL
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 19 at SQL statement
|
||||
INFO: z is NULL
|
||||
CONTEXT: SQL statement "CALL p3(r1,r2,s)"
|
||||
PL/pgSQL function inline_code_block line 19 at SQL statement
|
||||
DROP FUNCTION func1;
|
||||
DROP FUNCTION func2;
|
||||
DROP FUNCTION func3;
|
||||
DROP FUNCTION func4;
|
||||
DROP PACKAGE r_types;
|
||||
NOTICE: drop cascades to 3 other objects
|
||||
DETAIL: drop cascades to function p1()
|
||||
--?.*
|
||||
--?.*
|
||||
DROP SCHEMA test_pkg_default_value;
|
||||
@ -783,6 +783,7 @@ test: plpgsql_array_of_record
|
||||
test: arrayinterface_ted
|
||||
test: function_default_test plpgsql_inout_param record_slow_sql_in_proc
|
||||
test: plpgsql_cursor_rowtype
|
||||
test: plpgsql_default_value_various_type
|
||||
test: plpgsql_assign_list
|
||||
test: plpgsql_package_type plpgsql_package_param
|
||||
test: plpgsql_record_attrname
|
||||
|
||||
@ -285,6 +285,7 @@ test: plpgsql_array_of_record
|
||||
test: arrayinterface_ted
|
||||
test: function_default_test plpgsql_inout_param
|
||||
test: plpgsql_cursor_rowtype
|
||||
test: plpgsql_default_value_various_type
|
||||
test: plpgsql_assign_list
|
||||
test: plpgsql_package_type plpgsql_package_param
|
||||
test: plpgsql_record_attrname
|
||||
|
||||
318
src/test/regress/sql/plpgsql_default_value_various_type.sql
Normal file
318
src/test/regress/sql/plpgsql_default_value_various_type.sql
Normal file
@ -0,0 +1,318 @@
|
||||
create schema test_pkg_default_value;
|
||||
set current_schema = test_pkg_default_value;
|
||||
|
||||
-- test default expr
|
||||
CREATE FUNCTION func1(num2 inout int,num3 inout int) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 9 + num3;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE FUNCTION func3(num2 inout int) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 2;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
CREATE FUNCTION func2(num1 inout int, st1 inout varchar(10), num2 inout int) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 9;
|
||||
raise info 'str1 is %', NVL(str1,'NULL');
|
||||
raise info 'str2 is %', NVL(str2,'NULL');
|
||||
raise info 'num1 is %', num1;
|
||||
raise info 'num2 is %', num2;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
CREATE FUNCTION func4(num2 inout int,num3 inout bool) RETURNS int
|
||||
AS $$
|
||||
DECLARE
|
||||
BEGIN
|
||||
num2 := num2 + 1;
|
||||
return num2;
|
||||
END
|
||||
$$
|
||||
LANGUAGE plpgsql;
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (+1));
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := 1+-9+8*(-7)+1*-2);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := 1+-9+8/-11*(-7)+1*-2*2/5);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := 8*-11*(-7)+1*-2*2/5+9);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := -1);
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f VARCHAR2(5) := 'abus');
|
||||
END r_types;
|
||||
/
|
||||
select adsrc from PG_ATTRDEF where adrelid in (select typrelid from PG_TYPE where typname ilike '%r_type_1%' limit 1);
|
||||
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', NVL(r1.f,'NULL');
|
||||
END;
|
||||
/
|
||||
|
||||
-- test expr error
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (1+));
|
||||
END r_types;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := +);
|
||||
END r_types;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (+));
|
||||
END r_types;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f int := (a+b));
|
||||
END r_types;
|
||||
/
|
||||
|
||||
-- normal default
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f VARCHAR2(5) := 'abcde', f2 VARCHAR2(5) := 'waxtr');
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f VARCHAR2(5) := 'a1c2e', f2 VARCHAR2(5) := 'w5x3r');
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', NVL(r1.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r1.f2,'NULL');
|
||||
raise info 'r2.f is %', NVL(r2.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r2.f2,'NULL');
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f date := '2001-9-28', f2 timestamp := '1957-06-13');
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f date := '2000-7-28', f2 timestamp := '1987-06-03');
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f boolean := true, f2 numeric := 19.578);
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f boolean := false, f2 numeric := 13.278);
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f money := 10.5, f2 int := 15);
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f money := 9.6, f2 int := 13);
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f integer := 10, f2 oid := 15);
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f integer := 9, f2 oid := 13);
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', r1.f;
|
||||
raise info 'r1.f2 is %', r1.f2;
|
||||
raise info 'r1.f is %', r2.f;
|
||||
raise info 'r1.f2 is %', r2.f2;
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f name := 'abcde', f2 text := 'waxtr');
|
||||
END r_types;
|
||||
/
|
||||
DECLARE
|
||||
TYPE r_type_2 IS RECORD (f name := 'a1c2e', f2 text := 'w5x3r');
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_type_2;
|
||||
BEGIN
|
||||
raise info 'r1.f is %', NVL(r1.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r1.f2,'NULL');
|
||||
raise info 'r2.f is %', NVL(r2.f,'NULL');
|
||||
raise info 'r1.f2 is %', NVL(r2.f2,'NULL');
|
||||
END;
|
||||
/
|
||||
|
||||
-- pkg param default
|
||||
CREATE OR REPLACE PACKAGE r_types IS
|
||||
TYPE r_type_1 IS RECORD (f VARCHAR2(5) := 'abcde', f2 VARCHAR2(5) := 'syutw');
|
||||
TYPE r_type_2 IS RECORD (f VARCHAR2(5));
|
||||
END r_types;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE p1 (
|
||||
x OUT r_types.r_type_1,
|
||||
y OUT r_types.r_type_2,
|
||||
z OUT VARCHAR2)
|
||||
AUTHID CURRENT_USER IS
|
||||
BEGIN
|
||||
raise info 'x.f is %', NVL(x.f,'NULL');
|
||||
raise info 'x.f2 is %', NVL(x.f2,'NULL');
|
||||
raise info 'y.f is %', NVL(y.f,'NULL');
|
||||
raise info 'z is %', NVL(z,'NULL');
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE p2 (
|
||||
x IN r_types.r_type_1,
|
||||
y IN r_types.r_type_2,
|
||||
z IN VARCHAR2)
|
||||
AUTHID CURRENT_USER IS
|
||||
BEGIN
|
||||
raise info 'x.f is %', NVL(x.f,'NULL');
|
||||
raise info 'x.f2 is %', NVL(x.f2,'NULL');
|
||||
raise info 'y.f is %', NVL(y.f,'NULL');
|
||||
raise info 'z is %', NVL(z,'NULL');
|
||||
END;
|
||||
/
|
||||
|
||||
CREATE OR REPLACE PROCEDURE p3 (
|
||||
x INOUT r_types.r_type_1,
|
||||
y INOUT r_types.r_type_2,
|
||||
z INOUT VARCHAR2)
|
||||
AUTHID CURRENT_USER IS
|
||||
BEGIN
|
||||
raise info 'x.f is %', NVL(x.f,'NULL');
|
||||
raise info 'x.f2 is %', NVL(x.f2,'NULL');
|
||||
raise info 'y.f is %', NVL(y.f,'NULL');
|
||||
raise info 'z is %', NVL(z,'NULL');
|
||||
END;
|
||||
/
|
||||
DECLARE
|
||||
r1 r_types.r_type_1;
|
||||
r2 r_types.r_type_2;
|
||||
s VARCHAR2(5) := 'fghij';
|
||||
BEGIN
|
||||
raise info '===============p1===================';
|
||||
p1 (r1, r2, s);
|
||||
raise info '===============p2===================';
|
||||
p2 (r1, r2, s);
|
||||
raise info '===============p3===================';
|
||||
p3 (r1, r2, s);
|
||||
r1.f:='waqrt';
|
||||
r1.f2:='bfgrf';
|
||||
r2.f:='nuytg';
|
||||
raise info '===============p1===================';
|
||||
p1 (r1, r2, s);
|
||||
raise info '===============p2===================';
|
||||
p2 (r1, r2, s);
|
||||
raise info '===============p3===================';
|
||||
p3 (r1, r2, s);
|
||||
END;
|
||||
/
|
||||
|
||||
DROP FUNCTION func1;
|
||||
DROP FUNCTION func2;
|
||||
DROP FUNCTION func3;
|
||||
DROP FUNCTION func4;
|
||||
DROP PACKAGE r_types;
|
||||
DROP SCHEMA test_pkg_default_value;
|
||||
Reference in New Issue
Block a user