summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/execute.c6
-rw-r--r--src/plproxy.h4
-rw-r--r--src/query.c2
-rw-r--r--src/type.c13
4 files changed, 19 insertions, 6 deletions
diff --git a/src/execute.c b/src/execute.c
index 00cd6ca..41ceec7 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -853,11 +853,11 @@ tag_hash_partitions(ProxyFunction *func, FunctionCallInfo fcinfo, int tag,
* and determine the element type information.
*/
static DatumArray *
-make_datum_array(ProxyFunction *func, ArrayType *v, Oid elem_type)
+make_datum_array(ProxyFunction *func, ArrayType *v, ProxyType *array_type)
{
DatumArray *da = palloc0(sizeof(*da));
- da->type = plproxy_find_type_info(func, elem_type, true);
+ da->type = plproxy_get_elem_type(func, array_type, true);
if (v)
deconstruct_array(v,
@@ -948,7 +948,7 @@ prepare_and_tag_partitions(ProxyFunction *func, FunctionCallInfo fcinfo)
plproxy_error(func, "split multi-dimensional arrays are not supported");
}
- arrays_to_split[i] = make_datum_array(func, v, func->arg_types[i]->elem_type);
+ arrays_to_split[i] = make_datum_array(func, v, func->arg_types[i]);
/* Check that the element counts match */
if (split_array_len < 0)
diff --git a/src/plproxy.h b/src/plproxy.h
index 9aad95a..4dd582e 100644
--- a/src/plproxy.h
+++ b/src/plproxy.h
@@ -214,7 +214,8 @@ typedef struct ProxyType
bool by_value; /* False if Datum is a pointer to data */
char alignment; /* Type alignment */
bool is_array; /* True if array */
- Oid elem_type; /* Array element type */
+ Oid elem_type_oid; /* Array element type oid */
+ struct ProxyType *elem_type_t; /* Elem type info, filled lazily */
short length; /* Type length */
/* I/O functions */
@@ -365,6 +366,7 @@ void plproxy_yyerror(const char *fmt,...);
/* type.c */
ProxyComposite *plproxy_composite_info(ProxyFunction *func, TupleDesc tupdesc);
ProxyType *plproxy_find_type_info(ProxyFunction *func, Oid oid, bool for_send);
+ProxyType *plproxy_get_elem_type(ProxyFunction *func, ProxyType *type, bool for_send);
char *plproxy_send_type(ProxyType *type, Datum val, bool allow_bin, int *len, int *fmt);
Datum plproxy_recv_type(ProxyType *type, char *str, int len, bool bin);
HeapTuple plproxy_recv_composite(ProxyComposite *meta, char **values, int *lengths, int *fmts);
diff --git a/src/query.c b/src/query.c
index 4386a20..78a7e53 100644
--- a/src/query.c
+++ b/src/query.c
@@ -251,7 +251,7 @@ plproxy_query_prepare(ProxyFunction *func, FunctionCallInfo fcinfo, ProxyQuery *
if (split_support && IS_SPLIT_ARG(func, idx))
/* for SPLIT arguments use array element type instead */
- types[i] = func->arg_types[idx]->elem_type;
+ types[i] = func->arg_types[idx]->elem_type_oid;
else
types[i] = func->arg_types[idx]->type_oid;
}
diff --git a/src/type.c b/src/type.c
index 3679d83..db4effe 100644
--- a/src/type.c
+++ b/src/type.c
@@ -139,6 +139,9 @@ plproxy_free_type(ProxyType *type)
if (type->name)
pfree(type->name);
+ if (type->elem_type_t)
+ plproxy_free_type(type->elem_type_t);
+
/* hopefully I/O functions do not use ->fn_extra */
pfree(type);
@@ -254,7 +257,8 @@ plproxy_find_type_info(ProxyFunction *func, Oid oid, bool for_send)
type->by_value = s_type->typbyval;
type->name = plproxy_func_strdup(func, namebuf);
type->is_array = (s_type->typelem != 0 && s_type->typlen == -1);
- type->elem_type = s_type->typelem;
+ type->elem_type_oid = s_type->typelem;
+ type->elem_type_t = NULL;
type->alignment = s_type->typalign;
type->length = s_type->typlen;
@@ -283,6 +287,13 @@ plproxy_find_type_info(ProxyFunction *func, Oid oid, bool for_send)
return type;
}
+/* Get cached type info for array elems */
+ProxyType *plproxy_get_elem_type(ProxyFunction *func, ProxyType *type, bool for_send)
+{
+ if (!type->elem_type_t)
+ type->elem_type_t = plproxy_find_type_info(func, type->elem_type_oid, for_send);
+ return type->elem_type_t;
+}
/* Convert a Datum to parameter for libpq */
char *