* fetch_array_arg_replace_nulls * * Fetch an array-valued argument in expanded form; if it's null, construct an * empty array value of the proper data type. Also cache basic element type * information in fn_extra. * * Caution: if the input is a read/write pointer, this returns the input * argument; so callers must be sure that their changes are "safe", that is * they cannot leave the arra
| 60 | * copying operations. |
| 61 | */ |
| 62 | static ExpandedArrayHeader * |
| 63 | fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno) |
| 64 | { |
| 65 | ExpandedArrayHeader *eah; |
| 66 | Oid element_type; |
| 67 | ArrayMetaState *my_extra; |
| 68 | MemoryContext resultcxt; |
| 69 | |
| 70 | /* If first time through, create datatype cache struct */ |
| 71 | my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; |
| 72 | if (my_extra == NULL) |
| 73 | { |
| 74 | my_extra = (ArrayMetaState *) |
| 75 | MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, |
| 76 | sizeof(ArrayMetaState)); |
| 77 | my_extra->element_type = InvalidOid; |
| 78 | fcinfo->flinfo->fn_extra = my_extra; |
| 79 | } |
| 80 | |
| 81 | /* Figure out which context we want the result in */ |
| 82 | if (!AggCheckCallContext(fcinfo, &resultcxt)) |
| 83 | resultcxt = CurrentMemoryContext; |
| 84 | |
| 85 | /* Now collect the array value */ |
| 86 | if (!PG_ARGISNULL(argno)) |
| 87 | { |
| 88 | MemoryContext oldcxt = MemoryContextSwitchTo(resultcxt); |
| 89 | |
| 90 | eah = PG_GETARG_EXPANDED_ARRAYX(argno, my_extra); |
| 91 | MemoryContextSwitchTo(oldcxt); |
| 92 | } |
| 93 | else |
| 94 | { |
| 95 | /* We have to look up the array type and element type */ |
| 96 | Oid arr_typeid = get_fn_expr_argtype(fcinfo->flinfo, argno); |
| 97 | |
| 98 | if (!OidIsValid(arr_typeid)) |
| 99 | ereport(ERROR, |
| 100 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
| 101 | errmsg("could not determine input data type"))); |
| 102 | element_type = get_element_type(arr_typeid); |
| 103 | if (!OidIsValid(element_type)) |
| 104 | ereport(ERROR, |
| 105 | (errcode(ERRCODE_DATATYPE_MISMATCH), |
| 106 | errmsg("input data type is not an array"))); |
| 107 | |
| 108 | eah = construct_empty_expanded_array(element_type, |
| 109 | resultcxt, |
| 110 | my_extra); |
| 111 | } |
| 112 | |
| 113 | return eah; |
| 114 | } |
| 115 | |
| 116 | /*----------------------------------------------------------------------------- |
| 117 | * array_append : |
no test coverage detected