aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/arrayfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/arrayfuncs.c')
-rw-r--r--src/backend/utils/adt/arrayfuncs.c222
1 files changed, 1 insertions, 221 deletions
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 43acdffcaf0..38a86452e3f 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.137 2007/02/27 23:48:07 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.138 2007/03/27 23:21:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -95,10 +95,6 @@ static void array_insert_slice(ArrayType *destArray, ArrayType *origArray,
int *st, int *endp,
int typlen, bool typbyval, char typalign);
static int array_cmp(FunctionCallInfo fcinfo);
-static Datum array_type_length_coerce_internal(ArrayType *src,
- int32 desttypmod,
- bool isExplicit,
- FmgrInfo *fmgr_info);
/*
@@ -4094,222 +4090,6 @@ array_insert_slice(ArrayType *destArray,
}
/*
- * array_type_coerce -- allow explicit or assignment coercion from
- * one array type to another.
- *
- * array_type_length_coerce -- the same, for cases where both type and length
- * coercion are done by a single function on the element type.
- *
- * Caller should have already verified that the source element type can be
- * coerced into the target element type.
- */
-Datum
-array_type_coerce(PG_FUNCTION_ARGS)
-{
- ArrayType *src = PG_GETARG_ARRAYTYPE_P(0);
- FmgrInfo *fmgr_info = fcinfo->flinfo;
-
- return array_type_length_coerce_internal(src, -1, false, fmgr_info);
-}
-
-Datum
-array_type_length_coerce(PG_FUNCTION_ARGS)
-{
- ArrayType *src = PG_GETARG_ARRAYTYPE_P(0);
- int32 desttypmod = PG_GETARG_INT32(1);
- bool isExplicit = PG_GETARG_BOOL(2);
- FmgrInfo *fmgr_info = fcinfo->flinfo;
-
- return array_type_length_coerce_internal(src, desttypmod,
- isExplicit, fmgr_info);
-}
-
-static Datum
-array_type_length_coerce_internal(ArrayType *src,
- int32 desttypmod,
- bool isExplicit,
- FmgrInfo *fmgr_info)
-{
- Oid src_elem_type = ARR_ELEMTYPE(src);
- typedef struct
- {
- Oid srctype;
- Oid desttype;
- FmgrInfo coerce_finfo;
- ArrayMapState amstate;
- } atc_extra;
- atc_extra *my_extra;
- FunctionCallInfoData locfcinfo;
-
- /*
- * We arrange to look up the coercion function only once per series of
- * calls, assuming the input data type doesn't change underneath us.
- * (Output type can't change.)
- */
- my_extra = (atc_extra *) fmgr_info->fn_extra;
- if (my_extra == NULL)
- {
- fmgr_info->fn_extra = MemoryContextAllocZero(fmgr_info->fn_mcxt,
- sizeof(atc_extra));
- my_extra = (atc_extra *) fmgr_info->fn_extra;
- }
-
- if (my_extra->srctype != src_elem_type)
- {
- Oid tgt_type = get_fn_expr_rettype(fmgr_info);
- Oid tgt_elem_type;
- Oid funcId;
-
- if (tgt_type == InvalidOid)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("could not determine target array type")));
-
- tgt_elem_type = get_element_type(tgt_type);
- if (tgt_elem_type == InvalidOid)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("target type is not an array")));
-
- /*
- * We don't deal with domain constraints yet, so bail out. This isn't
- * currently a problem, because we also don't support arrays of domain
- * type elements either. But in the future we might. At that point
- * consideration should be given to removing the check below and
- * adding a domain constraints check to the coercion.
- */
- if (getBaseType(tgt_elem_type) != tgt_elem_type)
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("array coercion to domain type elements not "
- "currently supported")));
-
- if (!find_coercion_pathway(tgt_elem_type, src_elem_type,
- COERCION_EXPLICIT, &funcId))
- {
- /* should never happen, but check anyway */
- elog(ERROR, "no conversion function from %s to %s",
- format_type_be(src_elem_type),
- format_type_be(tgt_elem_type));
- }
- if (OidIsValid(funcId))
- fmgr_info_cxt(funcId, &my_extra->coerce_finfo, fmgr_info->fn_mcxt);
- else
- my_extra->coerce_finfo.fn_oid = InvalidOid;
- my_extra->srctype = src_elem_type;
- my_extra->desttype = tgt_elem_type;
- }
-
- /*
- * If it's binary-compatible, modify the element type in the array header,
- * but otherwise leave the array as we received it.
- */
- if (my_extra->coerce_finfo.fn_oid == InvalidOid)
- {
- ArrayType *result;
-
- result = (ArrayType *) DatumGetPointer(datumCopy(PointerGetDatum(src),
- false, -1));
- ARR_ELEMTYPE(result) = my_extra->desttype;
- PG_RETURN_ARRAYTYPE_P(result);
- }
-
- /*
- * Use array_map to apply the function to each array element.
- *
- * We pass on the desttypmod and isExplicit flags whether or not the
- * function wants them.
- */
- InitFunctionCallInfoData(locfcinfo, &my_extra->coerce_finfo, 3,
- NULL, NULL);
- locfcinfo.arg[0] = PointerGetDatum(src);
- locfcinfo.arg[1] = Int32GetDatum(desttypmod);
- locfcinfo.arg[2] = BoolGetDatum(isExplicit);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.argnull[2] = false;
-
- return array_map(&locfcinfo, my_extra->srctype, my_extra->desttype,
- &my_extra->amstate);
-}
-
-/*
- * array_length_coerce -- apply the element type's length-coercion routine
- * to each element of the given array.
- */
-Datum
-array_length_coerce(PG_FUNCTION_ARGS)
-{
- ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
- int32 desttypmod = PG_GETARG_INT32(1);
- bool isExplicit = PG_GETARG_BOOL(2);
- FmgrInfo *fmgr_info = fcinfo->flinfo;
- typedef struct
- {
- Oid elemtype;
- FmgrInfo coerce_finfo;
- ArrayMapState amstate;
- } alc_extra;
- alc_extra *my_extra;
- FunctionCallInfoData locfcinfo;
-
- /* If no typmod is provided, shortcircuit the whole thing */
- if (desttypmod < 0)
- PG_RETURN_ARRAYTYPE_P(v);
-
- /*
- * We arrange to look up the element type's coercion function only once
- * per series of calls, assuming the element type doesn't change
- * underneath us.
- */
- my_extra = (alc_extra *) fmgr_info->fn_extra;
- if (my_extra == NULL)
- {
- fmgr_info->fn_extra = MemoryContextAllocZero(fmgr_info->fn_mcxt,
- sizeof(alc_extra));
- my_extra = (alc_extra *) fmgr_info->fn_extra;
- }
-
- if (my_extra->elemtype != ARR_ELEMTYPE(v))
- {
- Oid funcId;
-
- funcId = find_typmod_coercion_function(ARR_ELEMTYPE(v));
-
- if (OidIsValid(funcId))
- fmgr_info_cxt(funcId, &my_extra->coerce_finfo, fmgr_info->fn_mcxt);
- else
- my_extra->coerce_finfo.fn_oid = InvalidOid;
- my_extra->elemtype = ARR_ELEMTYPE(v);
- }
-
- /*
- * If we didn't find a coercion function, return the array unmodified
- * (this should not happen in the normal course of things, but might
- * happen if this function is called manually).
- */
- if (my_extra->coerce_finfo.fn_oid == InvalidOid)
- PG_RETURN_ARRAYTYPE_P(v);
-
- /*
- * Use array_map to apply the function to each array element.
- *
- * Note: we pass isExplicit whether or not the function wants it ...
- */
- InitFunctionCallInfoData(locfcinfo, &my_extra->coerce_finfo, 3,
- NULL, NULL);
- locfcinfo.arg[0] = PointerGetDatum(v);
- locfcinfo.arg[1] = Int32GetDatum(desttypmod);
- locfcinfo.arg[2] = BoolGetDatum(isExplicit);
- locfcinfo.argnull[0] = false;
- locfcinfo.argnull[1] = false;
- locfcinfo.argnull[2] = false;
-
- return array_map(&locfcinfo, ARR_ELEMTYPE(v), ARR_ELEMTYPE(v),
- &my_extra->amstate);
-}
-
-/*
* accumArrayResult - accumulate one (more) Datum for an array result
*
* astate is working state (NULL on first call)