summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoey Adams2011-01-17 19:13:35 +0000
committerJoey Adams2011-01-17 19:16:21 +0000
commit4869261b8a1ea6186b5d0c06d97c4296a2ce7bcf (patch)
tree2ec8e7c2a711eea08bee259ab0beb038c61a9d45
parent75b17eeca0394e27759acf2f6b039851a5a28f98 (diff)
Removed FN_EXTRA macro and made getEnumLabelOids validate its entire input.
-rw-r--r--json_io.c9
-rw-r--r--json_op.c6
-rw-r--r--util.c11
-rw-r--r--util.h34
4 files changed, 16 insertions, 44 deletions
diff --git a/json_io.c b/json_io.c
index 2510d49..315191f 100644
--- a/json_io.c
+++ b/json_io.c
@@ -199,15 +199,16 @@ to_json(PG_FUNCTION_ARGS)
TypeInfo *typeInfo;
json_type target_type;
- typeInfo = FN_EXTRA();
+ typeInfo = fcinfo->flinfo->fn_extra;
if (typeInfo == NULL)
{
- typeInfo = FN_EXTRA_ALLOC(sizeof(TypeInfo));
- getTypeInfo(typeInfo, argtype, IOFunc_output, FN_MCXT());
+ typeInfo = fcinfo->flinfo->fn_extra =
+ MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(TypeInfo));
+ getTypeInfo(typeInfo, argtype, IOFunc_output, fcinfo->flinfo->fn_mcxt);
}
else if (typeInfo->type != argtype)
{
- getTypeInfo(typeInfo, argtype, IOFunc_output, FN_MCXT());
+ getTypeInfo(typeInfo, argtype, IOFunc_output, fcinfo->flinfo->fn_mcxt);
}
target_type = decide_json_type(argtype, typeInfo->typcategory);
diff --git a/json_op.c b/json_op.c
index f0a3ed2..77ab242 100644
--- a/json_op.c
+++ b/json_op.c
@@ -60,10 +60,12 @@ json_get_type(PG_FUNCTION_ARGS)
if (!json_type_is_valid(type))
report_corrupt_json();
- label_oids = FN_EXTRA();
+ label_oids = fcinfo->flinfo->fn_extra;
if (label_oids == NULL)
{
- label_oids = FN_EXTRA_ALLOC(JSON_TYPE_COUNT * sizeof(Oid));
+ label_oids = fcinfo->flinfo->fn_extra =
+ MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
+ JSON_TYPE_COUNT * sizeof(Oid));
getEnumLabelOids("json_type_t", enum_labels, label_oids, JSON_TYPE_COUNT);
}
diff --git a/util.c b/util.c
index 97c08d4..173e982 100644
--- a/util.c
+++ b/util.c
@@ -61,7 +61,7 @@ enum_label_cmp(const void *left, const void *right)
* return values of a custom enum type from a C function.
*
* Callers should typically cache the OIDs produced by this function
- * using FN_EXTRA, as retrieving enum label OIDs is somewhat expensive.
+ * using fn_extra, as retrieving enum label OIDs is somewhat expensive.
*
* Every labels[i].index must be between 0 and count, and oid_out
* must be allocated to hold count items. Note that getEnumLabelOids
@@ -106,8 +106,14 @@ getEnumLabelOids(const char *typname, EnumLabel labels[], Oid oid_out[], int cou
qsort(labels, count, sizeof(EnumLabel), enum_label_cmp);
for (i = 0; i < count; i++)
+ {
+ /* Initialize oid_out items to InvalidOid. */
oid_out[i] = InvalidOid;
+ /* Make sure EnumLabel indices are in range. */
+ Assert(labels[i].index >= 0 && labels[i].index < count);
+ }
+
list = SearchSysCacheList1(ENUMTYPOIDNAME,
ObjectIdGetDatum(enumtypoid));
total = list->n_members;
@@ -121,10 +127,7 @@ getEnumLabelOids(const char *typname, EnumLabel labels[], Oid oid_out[], int cou
key.label = NameStr(en->enumlabel);
found = bsearch(&key, labels, count, sizeof(EnumLabel), enum_label_cmp);
if (found != NULL)
- {
- Assert(found->index >= 0 && found->index < count);
oid_out[found->index] = oid;
- }
}
ReleaseCatCacheList(list);
diff --git a/util.h b/util.h
index 6877ab5..d7d8795 100644
--- a/util.h
+++ b/util.h
@@ -42,40 +42,6 @@ typedef struct
const char *label;
} EnumLabel;
-/*
- * FN_EXTRA, FN_EXTRA_ALLOC, FN_MCXT
- * Macros for manipulating context preserved across function calls.
- *
- * FN_EXTRA is typically used for caching lookups and other nontrivial
- * operations across multiple calls of a user-defined function.
- *
- * Do not use FN_EXTRA in a set-returning function. Use user_fctx instead.
- *
- * Typical usage looks like:
- *
- * 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) \
- (fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, size))
-
-/*
- * Data allocated inside of FN_EXTRA() should be allocated into FN_MCXT()
- * so it is preserved across calls
- */
-#define FN_MCXT() (fcinfo->flinfo->fn_mcxt)
void getTypeInfo(TypeInfo *d, Oid type, IOFuncSelector which_func, MemoryContext mcxt);