From 16a17e23bbd2008c75faae24bb76f0fa28d0ab39 Mon Sep 17 00:00:00 2001 From: msepga Date: Tue, 15 Oct 2024 19:01:39 -0400 Subject: [PATCH] Mock `plpgsql_build_datatype_arrayof` with special type handling --- scripts/extract_source.rb | 39 ++++++++++++++++++++++- src/postgres/src_pl_plpgsql_src_pl_comp.c | 39 ++++++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/scripts/extract_source.rb b/scripts/extract_source.rb index 7c4f3e30..ed6b9925 100644 --- a/scripts/extract_source.rb +++ b/scripts/extract_source.rb @@ -576,7 +576,44 @@ def write_out return typ; } )) -runner.mock('plpgsql_build_datatype_arrayof', 'PLpgSQL_type * plpgsql_build_datatype_arrayof(PLpgSQL_type *dtype) { PLpgSQL_type *typ; typ = (PLpgSQL_type *) palloc0(sizeof(PLpgSQL_type)); typ->typname = pstrdup("UNKNOWN"); typ->ttype = PLPGSQL_TTYPE_SCALAR; return typ; }') +runner.mock('plpgsql_build_datatype_arrayof', %( +PLpgSQL_type * plpgsql_build_datatype_arrayof(PLpgSQL_type *dtype) +{ + if (dtype->typisarray) + return dtype; + + PLpgSQL_type *array_type; + array_type = (PLpgSQL_type *) palloc0(sizeof(PLpgSQL_type)); + + array_type->ttype = PLPGSQL_TTYPE_REC; + array_type->atttypmod = dtype->atttypmod; + array_type->collation = dtype->collation; + + array_type->typisarray = true; + + switch(dtype->typoid) + { + case BOOLOID: + array_type->typoid = BOOLARRAYOID; + array_type->typname = pstrdup("boolean[]"); + break; + case INT4OID: + array_type->typoid = INT4ARRAYOID; + array_type->typname = pstrdup("integer[]"); + break; + case TEXTOID: + array_type->typoid = TEXTARRAYOID; + array_type->typname = pstrdup("text[]"); + break; + default: + array_type->typname = pstrdup("UNKNOWN"); + break; + } + array_type->typoid = dtype->typoid; + + return array_type; +} +)) runner.mock('parse_datatype', 'static PLpgSQL_type * parse_datatype(const char *string, int location) { PLpgSQL_type *typ; typ = (PLpgSQL_type *) palloc0(sizeof(PLpgSQL_type)); typ->typname = pstrdup(string); typ->ttype = strcmp(string, "RECORD") == 0 ? PLPGSQL_TTYPE_REC : PLPGSQL_TTYPE_SCALAR; return typ; }') runner.mock('get_collation_oid', 'Oid get_collation_oid(List *name, bool missing_ok) { return -1; }') runner.mock('plpgsql_parse_wordtype', 'PLpgSQL_type * plpgsql_parse_wordtype(char *ident) { return NULL; }') diff --git a/src/postgres/src_pl_plpgsql_src_pl_comp.c b/src/postgres/src_pl_plpgsql_src_pl_comp.c index dc7746c9..149ab679 100644 --- a/src/postgres/src_pl_plpgsql_src_pl_comp.c +++ b/src/postgres/src_pl_plpgsql_src_pl_comp.c @@ -940,7 +940,44 @@ PLpgSQL_type * plpgsql_build_datatype(Oid typeOid, int32 typmod, Oid collation, /* * Build an array type for the element type specified as argument. */ -PLpgSQL_type * plpgsql_build_datatype_arrayof(PLpgSQL_type *dtype) { PLpgSQL_type *typ; typ = (PLpgSQL_type *) palloc0(sizeof(PLpgSQL_type)); typ->typname = pstrdup("UNKNOWN"); typ->ttype = PLPGSQL_TTYPE_SCALAR; return typ; } + +PLpgSQL_type * plpgsql_build_datatype_arrayof(PLpgSQL_type *dtype) +{ + if (dtype->typisarray) + return dtype; + + PLpgSQL_type *array_type; + array_type = (PLpgSQL_type *) palloc0(sizeof(PLpgSQL_type)); + + array_type->ttype = PLPGSQL_TTYPE_REC; + array_type->atttypmod = dtype->atttypmod; + array_type->collation = dtype->collation; + + array_type->typisarray = true; + + switch(dtype->typoid) + { + case BOOLOID: + array_type->typoid = BOOLARRAYOID; + array_type->typname = pstrdup("boolean[]"); + break; + case INT4OID: + array_type->typoid = INT4ARRAYOID; + array_type->typname = pstrdup("integer[]"); + break; + case TEXTOID: + array_type->typoid = TEXTARRAYOID; + array_type->typname = pstrdup("text[]"); + break; + default: + array_type->typname = pstrdup("UNKNOWN"); + break; + } + array_type->typoid = dtype->typoid; + + return array_type; +} + /*