diff options
author | Joey Adams | 2011-01-17 19:13:35 +0000 |
---|---|---|
committer | Joey Adams | 2011-01-17 19:16:21 +0000 |
commit | 4869261b8a1ea6186b5d0c06d97c4296a2ce7bcf (patch) | |
tree | 2ec8e7c2a711eea08bee259ab0beb038c61a9d45 | |
parent | 75b17eeca0394e27759acf2f6b039851a5a28f98 (diff) |
Removed FN_EXTRA macro and made getEnumLabelOids validate its entire input.
-rw-r--r-- | json_io.c | 9 | ||||
-rw-r--r-- | json_op.c | 6 | ||||
-rw-r--r-- | util.c | 11 | ||||
-rw-r--r-- | util.h | 34 |
4 files changed, 16 insertions, 44 deletions
@@ -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); @@ -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); } @@ -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); @@ -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); |