修复package数组没有保留typmod的bug
This commit is contained in:
@ -1309,12 +1309,8 @@ HeapTuple FindPkgVariableType(ParseState* pstate, const TypeName* typname, int32
|
||||
}
|
||||
|
||||
/* handle var.col%TYPE firsr */
|
||||
tup = FindRowVarColType(typname->names);
|
||||
tup = FindRowVarColType(typname->names, NULL, NULL, typmod_p);
|
||||
if (tup != NULL) {
|
||||
typmod = typenameTypeMod(pstate, typname, (Type)tup);
|
||||
if (typmod_p != NULL) {
|
||||
*typmod_p = typmod;
|
||||
}
|
||||
return tup;
|
||||
}
|
||||
|
||||
|
||||
@ -8546,11 +8546,12 @@ read_datatype(int tok)
|
||||
HeapTuple tup = NULL;
|
||||
int collectionType = PLPGSQL_COLLECTION_NONE;
|
||||
Oid tableOfIndexType = InvalidOid;
|
||||
tup = FindRowVarColType(dtnames, &collectionType, &tableOfIndexType);
|
||||
int32 typMod = -1;
|
||||
tup = FindRowVarColType(dtnames, &collectionType, &tableOfIndexType, &typMod);
|
||||
if (tup != NULL) {
|
||||
Oid typOid = typeTypeId(tup);
|
||||
ReleaseSysCache(tup);
|
||||
PLpgSQL_type* type = plpgsql_build_datatype(typOid, -1, InvalidOid);
|
||||
PLpgSQL_type* type = plpgsql_build_datatype(typOid, typMod, InvalidOid);
|
||||
if (OidIsValid(tableOfIndexType)) {
|
||||
type->collectionType = collectionType;
|
||||
type->tableOfIndexType = tableOfIndexType;
|
||||
|
||||
@ -2050,7 +2050,7 @@ void getTableofTypeFromVar(PLpgSQL_var* var, int* collectionType, Oid* tableofIn
|
||||
}
|
||||
}
|
||||
|
||||
HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofIndexType)
|
||||
HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofIndexType, int32* typMod)
|
||||
{
|
||||
if (u_sess->plsql_cxt.curr_compile_context == NULL) {
|
||||
return NULL;
|
||||
@ -2110,10 +2110,16 @@ HeapTuple FindRowVarColType(List* nameList, int* collectionType, Oid* tableofInd
|
||||
if (datum->dtype == PLPGSQL_DTYPE_VAR) {
|
||||
/* scalar variable, just return the datatype */
|
||||
typOid = ((PLpgSQL_var*)datum)->datatype->typoid;
|
||||
if (typMod != NULL) {
|
||||
*typMod = ((PLpgSQL_var*)datum)->datatype->atttypmod;
|
||||
}
|
||||
getTableofTypeFromVar((PLpgSQL_var*)datum, collectionType, tableofIndexType);
|
||||
} else if (datum->dtype == PLPGSQL_DTYPE_ROW) {
|
||||
/* row variable, need to build a new one */
|
||||
typOid = ((PLpgSQL_row*)datum)->rowtupdesc->tdtypeid;
|
||||
if (typMod != NULL) {
|
||||
*typMod = ((PLpgSQL_row*)datum)->rowtupdesc->tdtypmod;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
*
|
||||
* -------------------------------------------------------------------------
|
||||
*/
|
||||
#include "utils/builtins.h"
|
||||
#include "utils/plpgsql.h"
|
||||
#include "utils/pl_package.h"
|
||||
#include "catalog/pg_type.h"
|
||||
@ -24,6 +25,7 @@
|
||||
|
||||
#define PG_KEYWORD(a, b, c) {a, b, c},
|
||||
#define LENGTH_OF_DOT_AND_STR_END 4
|
||||
#define INT32_STRING_SIZE 12
|
||||
/*
|
||||
* A word about keywords:
|
||||
*
|
||||
@ -552,6 +554,9 @@ void plpgsql_append_object_typename(StringInfo buf, PLpgSQL_type *var_type)
|
||||
{
|
||||
errno_t ret;
|
||||
char* typcast = "::";
|
||||
char* left = "(";
|
||||
char* right = ")";
|
||||
char* dot = ",";
|
||||
appendBinaryStringInfo(buf, typcast, 2);
|
||||
|
||||
int len = strlen(var_type->typname) + strlen(var_type->typnamespace) + LENGTH_OF_DOT_AND_STR_END;
|
||||
@ -565,6 +570,24 @@ void plpgsql_append_object_typename(StringInfo buf, PLpgSQL_type *var_type)
|
||||
ret = strcat_s(typname, len, "\"");
|
||||
securec_check(ret, "\0", "\0");
|
||||
appendBinaryStringInfo(buf, typname, strlen(typname));
|
||||
if (var_type->atttypmod != -1) {
|
||||
appendBinaryStringInfo(buf, left, 1);
|
||||
if (var_type->typoid == NUMERICOID) {
|
||||
int32 typmod = var_type->atttypmod - VARHDRSZ;
|
||||
char* precision = (char*)palloc(INT32_STRING_SIZE);
|
||||
char* scale = (char*)palloc(INT32_STRING_SIZE);
|
||||
pg_ltoa((int32)(((uint32)(typmod) >> 16) & 0xffff), precision);
|
||||
pg_ltoa((int32)(((uint32)typmod) & 0xffff), scale);
|
||||
appendBinaryStringInfo(buf, precision, strlen(precision));
|
||||
appendBinaryStringInfo(buf, dot, 1);
|
||||
appendBinaryStringInfo(buf, scale, strlen(scale));
|
||||
} else {
|
||||
char* typMod = (char*)palloc(INT32_STRING_SIZE);
|
||||
pg_ltoa(var_type->atttypmod, typMod);
|
||||
appendBinaryStringInfo(buf, typMod, strlen(typMod));
|
||||
}
|
||||
appendBinaryStringInfo(buf, right, 1);
|
||||
}
|
||||
pfree_ext(typname);
|
||||
}
|
||||
|
||||
|
||||
@ -71,5 +71,6 @@ extern List* GetPackageListName(const char* pkgName, const Oid nspOid);
|
||||
|
||||
extern HeapTuple getPLpgsqlVarTypeTup(char* word);
|
||||
|
||||
extern HeapTuple FindRowVarColType(List* nameList, int* collectionType = NULL, Oid* tableofIndexType = NULL);
|
||||
extern HeapTuple FindRowVarColType(List* nameList, int* collectionType = NULL, Oid* tableofIndexType = NULL,
|
||||
int32* typMod = NULL);
|
||||
#endif
|
||||
|
||||
23
src/test/regress/expected/package_typmod_test.out
Normal file
23
src/test/regress/expected/package_typmod_test.out
Normal file
@ -0,0 +1,23 @@
|
||||
create type ty1 is (id int,cat1 bit(5));
|
||||
create or replace package pak1 as
|
||||
var ty1;
|
||||
type tp_tb1 is table of var.cat1%type;
|
||||
tb1 tp_tb1;
|
||||
procedure p1;
|
||||
end pak1 ;
|
||||
/
|
||||
create or replace package body pak1 as
|
||||
procedure p1 as
|
||||
begin
|
||||
tb1=tp_tb1(12,13,5,0);
|
||||
raise info '%', tb1;
|
||||
end;
|
||||
end pak1;
|
||||
/
|
||||
call pak1.p1();
|
||||
INFO: {01100,01101,00101,00000}
|
||||
p1
|
||||
----
|
||||
|
||||
(1 row)
|
||||
|
||||
@ -716,7 +716,7 @@ test: plpgsql_assign_list
|
||||
test: plpgsql_package_type plpgsql_package_param
|
||||
test: plpgsql_record_attrname
|
||||
test: plpgsql_insert_record
|
||||
test: hw_package_variable
|
||||
test: hw_package_variable package_typmod_test
|
||||
test: autonomous_cursor
|
||||
test: plpgsql_reset_session
|
||||
#test: plancache limit rangefuncs prepare
|
||||
|
||||
17
src/test/regress/sql/package_typmod_test.sql
Normal file
17
src/test/regress/sql/package_typmod_test.sql
Normal file
@ -0,0 +1,17 @@
|
||||
create type ty1 is (id int,cat1 bit(5));
|
||||
create or replace package pak1 as
|
||||
var ty1;
|
||||
type tp_tb1 is table of var.cat1%type;
|
||||
tb1 tp_tb1;
|
||||
procedure p1;
|
||||
end pak1 ;
|
||||
/
|
||||
create or replace package body pak1 as
|
||||
procedure p1 as
|
||||
begin
|
||||
tb1=tp_tb1(12,13,5,0);
|
||||
raise info '%', tb1;
|
||||
end;
|
||||
end pak1;
|
||||
/
|
||||
call pak1.p1();
|
||||
Reference in New Issue
Block a user