text: 
  Datum vec_coalesce(PG_FUNCTION_ARGS);
  PG_FUNCTION_INFO_V1(vec_coalesce);
  
  /**
   * Coalesce elements in an array to a non-null value.
   *
   * This function takes an array of n elements plus a non-null value of the same type
   * as the array. It returns a new array with any NULL elements of the input array
   * replaced by the given non-null value.
   */
  Datum
  vec_coalesce(PG_FUNCTION_ARGS)
  {
    Oid scalarTypeId = get_fn_expr_argtype(fcinfo->flinfo, 1);
    Oid elemTypeId;
    int16 elemTypeWidth;
    bool elemTypeByValue;
    char elemTypeAlignmentCode;
    int inputLength;
    ArrayType *inputArray, *retArray;
    Datum *inputContent, scalarContent, *retContent = 0;
    bool *inputNulls, *retNulls;
    int i, j;
    int dims[1];
    int lbs[1];
  
    if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) {
      PG_RETURN_NULL();
    }
  
    inputArray = PG_GETARG_ARRAYTYPE_P(0);
  
    if (ARR_NDIM(inputArray) == 0) {
      PG_RETURN_NULL();
    }
    if (ARR_NDIM(inputArray) > 1) {
      ereport(ERROR, (errmsg("vec_coalesce: one-dimensional array is required")));
    }
  
    elemTypeId = ARR_ELEMTYPE(inputArray);
  
    if (elemTypeId != INT2OID &&
        elemTypeId != INT4OID &&
        elemTypeId != INT8OID &&
        elemTypeId != FLOAT4OID &&
        elemTypeId != FLOAT8OID &&
        elemTypeId != NUMERICOID) {
      ereport(ERROR, (errmsg("vec_coalesce input must be array of SMALLINT, INTEGER, BIGINT, REAL, DOUBLE PRECISION, or NUMERIC")));
    }
    if (elemTypeId != scalarTypeId) {
      ereport(ERROR, (errmsg("vec_coalesce input array and scalar must be the same type")));
    }
  
    get_typlenbyvalalign(scalarTypeId, &elemTypeWidth, &elemTypeByValue, &elemTypeAlignmentCode);
    deconstruct_array(inputArray, scalarTypeId, elemTypeWidth, elemTypeByValue, elemTypeAlignmentCode,
        &inputContent, &inputNulls, &inputLength);
  
    scalarContent = PG_GETARG_DATUM(1);
  
    for (i = 0; i < inputLength; i++) {
      if (inputNulls[i]) {
        if (!retContent) {
          // lazy-init return structures now
          retContent = palloc0(sizeof(Datum) * inputLength);
          retNulls = palloc0(sizeof(bool) * inputLength);
  
          // back-fill skipped values as needed
          for (j = 0; j < i; j++) {
            retNulls[j] = false;
            retContent[j] = inputContent[j];
          }
        }
        retNulls[i] = false;
        retContent[i] = scalarContent;
      } else if (retContent) {
        retNulls[i] = false;
        retContent[i] = inputContent[i];
      }
    }
  
    // if we found no NULL elements; simply return the input to save a few cycles
    if (!retContent) PG_RETURN_ARRAYTYPE_P(inputArray);
  
    dims[0] = inputLength;
    lbs[0] = 1;
  
    retArray = construct_md_array(retContent, retNulls, 1, dims, lbs,
        scalarTypeId, elemTypeWidth, elemTypeByValue, elemTypeAlignmentCode);
  
    PG_RETURN_ARRAYTYPE_P(retArray);
  }
  
  