From: Marko Kreen Date: Wed, 12 Oct 2011 09:48:56 +0000 (+0300) Subject: SPLIT: fix elem type info leak X-Git-Tag: plproxy_2_3~5 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=76724dd2540f63ece6fcb39609bb1fb42c0b22b1;p=plproxy.git SPLIT: fix elem type info leak --- 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 *