修复package数组没有保留typmod的bug

This commit is contained in:
luozihao
2022-09-21 21:37:18 +08:00
parent deba6c0140
commit 45716f8302
8 changed files with 77 additions and 10 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View 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)

View File

@ -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

View 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();