summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Adams2010-08-05 22:33:38 +0000
committerJoey Adams2010-08-05 22:33:38 +0000
commitc713ff84a84722381619769d7f15d99591eb23ae (patch)
treecf659e1e415c6e9afd64a048e810c27a8e485c2f
parente2aa55c3495632acae227967dc850e20748796e5 (diff)
Simplified and documented getTypeInfo.
Also touched up documentation for FN_EXTRA a bit.
-rw-r--r--json_io.c13
-rw-r--r--util.c43
-rw-r--r--util.h40
3 files changed, 51 insertions, 45 deletions
diff --git a/json_io.c b/json_io.c
index cbd2aa0..0380e5e 100644
--- a/json_io.c
+++ b/json_io.c
@@ -200,13 +200,15 @@ to_json(PG_FUNCTION_ARGS)
json_type target_type;
typeInfo = FN_EXTRA();
- if (!typeInfo)
+ if (typeInfo == NULL)
{
typeInfo = FN_EXTRA_ALLOC(sizeof(TypeInfo));
- initTypeInfo(typeInfo, FN_MCXT());
+ getTypeInfo(typeInfo, argtype, IOFunc_output, FN_MCXT());
+ }
+ else if (typeInfo->type != argtype)
+ {
+ getTypeInfo(typeInfo, argtype, IOFunc_output, FN_MCXT());
}
-
- getTypeInfo(typeInfo, argtype, IOFunc_output);
target_type = decide_json_type(argtype, typeInfo->typcategory);
@@ -352,8 +354,7 @@ array_to_json(Datum datum)
* computing now) in the fcinfo->flinfo->fn_mcxt of to_json like we do
* with the TypeInfo of the array itself.
*/
- initTypeInfo(&element_typeinfo, CurrentMemoryContext);
- getTypeInfo(&element_typeinfo, element_type, IOFunc_output);
+ getTypeInfo(&element_typeinfo, element_type, IOFunc_output, CurrentMemoryContext);
target_type = decide_json_type(element_type, element_typeinfo.typcategory);
diff --git a/util.c b/util.c
index 48cd4ff..1fa4798 100644
--- a/util.c
+++ b/util.c
@@ -15,30 +15,35 @@
#include "mb/pg_wchar.h"
#include "utils/syscache.h"
+/*
+ * getTypeInfo
+ * Retrieve information about a type, along with either its
+ * input, output, binary receive, or binary send procedure.
+ *
+ * which_func should be one of:
+ * IOFunc_input
+ * IOFunc_output
+ * IOFunc_receive
+ * IOFunc_send
+ *
+ * mcxt is the memory context the IO function selected will use to store
+ * subsidiary data. The memory context should live at least as long as
+ * the TypeInfo structure you specify.
+ */
void
-initTypeInfo(TypeInfo *d, MemoryContext mcxt)
+getTypeInfo(TypeInfo *d, Oid type, IOFuncSelector which_func, MemoryContext mcxt)
{
+ d->type = type;
+ d->which_func = which_func;
d->mcxt = mcxt;
- d->not_set = true;
-}
-void
-getTypeInfo(TypeInfo *d, Oid type, IOFuncSelector which_func)
-{
- if (d->not_set || d->type != type || d->which_func != which_func)
- {
- get_type_io_data(type, which_func,
- &d->typlen, &d->typbyval, &d->typalign,
- &d->typdelim, &d->typioparam, &d->typiofunc);
- fmgr_info_cxt(d->typiofunc, &d->proc, d->mcxt);
+ get_type_io_data(type, which_func,
+ &d->typlen, &d->typbyval, &d->typalign,
+ &d->typdelim, &d->typioparam, &d->typiofunc);
+ fmgr_info_cxt(d->typiofunc, &d->proc, d->mcxt);
- get_type_category_preferred(type,
- &d->typcategory, &d->typispreferred);
-
- d->type = type;
- d->which_func = which_func;
- d->not_set = false;
- }
+ get_type_category_preferred(type,
+ &d->typcategory, &d->typispreferred);
}
Oid
diff --git a/util.h b/util.h
index f5bff4c..e26bef5 100644
--- a/util.h
+++ b/util.h
@@ -18,26 +18,29 @@
#include "utils/lsyscache.h"
/*
- * Macros for manipulating context preserved across function calls.
+ * FN_EXTRA, FN_EXTRA_ALLOC, FN_MCXT
+ * Macros for manipulating context preserved across function calls.
*
- * FN_EXTRA is primarily used for caching lookups across
- * multiple calls of a function.
+ * FN_EXTRA is typically used for caching lookups and other nontrivial
+ * operations across multiple calls of a user-defined function.
*
- * Typical usage looks like:
+ * Do not use FN_EXTRA in a set-returning function. Use user_fctx instead.
*
- * my_extra = FN_EXTRA();
- * if (!my_extra)
- * {
- * my_extra = FN_EXTRA_ALLOC(sizeof(MyExtra));
- * my_extra->type_name = NULL;
- * }
+ * Typical usage looks like:
*
- * if (my_extra->type_name == NULL ||
- * strcmp(my_extra->type_name, type_name) != 0)
- * {
- * my_extra->type_name = MemoryContextStrdup(FN_MCXT(), type_name);
- * my_extra->type_id = TypenameGetTypid(my_extra->type_name);
- * }
+ * my_extra = FN_EXTRA();
+ * if (my_extra == NULL)
+ * {
+ * my_extra = FN_EXTRA_ALLOC(sizeof(MyExtra));
+ * my_extra->type_name = NULL;
+ * }
+ *
+ * if (my_extra->type_name == NULL ||
+ * strcmp(my_extra->type_name, type_name) != 0)
+ * {
+ * my_extra->type_name = MemoryContextStrdup(FN_MCXT(), type_name);
+ * my_extra->type_id = TypenameGetTypid(my_extra->type_name);
+ * }
*/
#define FN_EXTRA() (fcinfo->flinfo->fn_extra)
#define FN_EXTRA_ALLOC(size) \
@@ -55,8 +58,6 @@ typedef struct
IOFuncSelector which_func;
MemoryContext mcxt;
- bool not_set;
-
int16 typlen;
bool typbyval;
char typalign;
@@ -69,8 +70,7 @@ typedef struct
bool typispreferred;
} TypeInfo;
-void initTypeInfo(TypeInfo *d, MemoryContext mcxt);
-void getTypeInfo(TypeInfo *d, Oid type, IOFuncSelector which_func);
+void getTypeInfo(TypeInfo *d, Oid type, IOFuncSelector which_func, MemoryContext mcxt);
Oid enumLabelToOid(const char *typname, const char *label);