SPLIT: fix elem type info leak
authorMarko Kreen <markokr@gmail.com>
Wed, 12 Oct 2011 09:48:56 +0000 (12:48 +0300)
committerMarko Kreen <markokr@gmail.com>
Wed, 12 Oct 2011 09:48:56 +0000 (12:48 +0300)
src/execute.c
src/plproxy.h
src/query.c
src/type.c

index 00cd6cade0c65a1c11a781e4fd2e7917f4942808..41ceec7a23ad0ed830634d4f7ac8fa960b8d6792 100644 (file)
@@ -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)
index 9aad95aee5fb0c95575b32939bc2be888c6ea6b7..4dd582eaa041bebacc386aea5f224728e3ce2ebe 100644 (file)
@@ -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);
index 4386a20e721b3e972eadbf611e1f1504bb1f28fc..78a7e539b32c51a3fb322d21d9fe2478cab8d0c6 100644 (file)
@@ -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;
        }
index 3679d832709bbaa004d0c7d89724bf071de0d528..db4effef645cb24699e3073f88a08790c20a797a 100644 (file)
@@ -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 *