mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Add array_remove() and array_replace() functions.
These functions support removing or replacing array element value(s) matching a given search value. Although intended mainly to support a future array-foreign-key feature, they seem useful in their own right. Marco Nenciarini and Gabriele Bartolini, reviewed by Alex Hunsaker
This commit is contained in:
@ -10316,6 +10316,12 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>array_prepend</primary>
|
<primary>array_prepend</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
|
<indexterm>
|
||||||
|
<primary>array_remove</primary>
|
||||||
|
</indexterm>
|
||||||
|
<indexterm>
|
||||||
|
<primary>array_replace</primary>
|
||||||
|
</indexterm>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
<primary>array_to_string</primary>
|
<primary>array_to_string</primary>
|
||||||
</indexterm>
|
</indexterm>
|
||||||
@ -10432,6 +10438,29 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
<entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
|
<entry><literal>array_prepend(1, ARRAY[2,3])</literal></entry>
|
||||||
<entry><literal>{1,2,3}</literal></entry>
|
<entry><literal>{1,2,3}</literal></entry>
|
||||||
</row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<literal>
|
||||||
|
<function>array_remove</function>(<type>anyarray</type>, <type>anyelement</type>)
|
||||||
|
</literal>
|
||||||
|
</entry>
|
||||||
|
<entry><type>anyarray</type></entry>
|
||||||
|
<entry>remove all elements equal to the given value from the array
|
||||||
|
(array must be one-dimensional)</entry>
|
||||||
|
<entry><literal>array_remove(ARRAY[1,2,3,2], 2)</literal></entry>
|
||||||
|
<entry><literal>{1,3}</literal></entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<literal>
|
||||||
|
<function>array_replace</function>(<type>anyarray</type>, <type>anyelement</type>, <type>anyelement</type>)
|
||||||
|
</literal>
|
||||||
|
</entry>
|
||||||
|
<entry><type>anyarray</type></entry>
|
||||||
|
<entry>replace each array element equal to the given value with a new value</entry>
|
||||||
|
<entry><literal>array_replace(ARRAY[1,2,5,4], 5, 3)</literal></entry>
|
||||||
|
<entry><literal>{1,2,3,4}</literal></entry>
|
||||||
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<literal>
|
<literal>
|
||||||
|
@ -124,6 +124,11 @@ static ArrayType *create_array_envelope(int ndims, int *dimv, int *lbv, int nbyt
|
|||||||
static ArrayType *array_fill_internal(ArrayType *dims, ArrayType *lbs,
|
static ArrayType *array_fill_internal(ArrayType *dims, ArrayType *lbs,
|
||||||
Datum value, bool isnull, Oid elmtype,
|
Datum value, bool isnull, Oid elmtype,
|
||||||
FunctionCallInfo fcinfo);
|
FunctionCallInfo fcinfo);
|
||||||
|
static ArrayType *array_replace_internal(ArrayType *array,
|
||||||
|
Datum search, bool search_isnull,
|
||||||
|
Datum replace, bool replace_isnull,
|
||||||
|
bool remove, Oid collation,
|
||||||
|
FunctionCallInfo fcinfo);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5174,3 +5179,304 @@ array_unnest(PG_FUNCTION_ARGS)
|
|||||||
SRF_RETURN_DONE(funcctx);
|
SRF_RETURN_DONE(funcctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* array_replace/array_remove support
|
||||||
|
*
|
||||||
|
* Find all array entries matching (not distinct from) search/search_isnull,
|
||||||
|
* and delete them if remove is true, else replace them with
|
||||||
|
* replace/replace_isnull. Comparisons are done using the specified
|
||||||
|
* collation. fcinfo is passed only for caching purposes.
|
||||||
|
*/
|
||||||
|
static ArrayType *
|
||||||
|
array_replace_internal(ArrayType *array,
|
||||||
|
Datum search, bool search_isnull,
|
||||||
|
Datum replace, bool replace_isnull,
|
||||||
|
bool remove, Oid collation,
|
||||||
|
FunctionCallInfo fcinfo)
|
||||||
|
{
|
||||||
|
ArrayType *result;
|
||||||
|
Oid element_type;
|
||||||
|
Datum *values;
|
||||||
|
bool *nulls;
|
||||||
|
int *dim;
|
||||||
|
int ndim;
|
||||||
|
int nitems,
|
||||||
|
nresult;
|
||||||
|
int i;
|
||||||
|
int32 nbytes = 0;
|
||||||
|
int32 dataoffset;
|
||||||
|
bool hasnulls;
|
||||||
|
int typlen;
|
||||||
|
bool typbyval;
|
||||||
|
char typalign;
|
||||||
|
char *arraydataptr;
|
||||||
|
bits8 *bitmap;
|
||||||
|
int bitmask;
|
||||||
|
bool changed = false;
|
||||||
|
TypeCacheEntry *typentry;
|
||||||
|
FunctionCallInfoData locfcinfo;
|
||||||
|
|
||||||
|
element_type = ARR_ELEMTYPE(array);
|
||||||
|
ndim = ARR_NDIM(array);
|
||||||
|
dim = ARR_DIMS(array);
|
||||||
|
nitems = ArrayGetNItems(ndim, dim);
|
||||||
|
|
||||||
|
/* Return input array unmodified if it is empty */
|
||||||
|
if (nitems <= 0)
|
||||||
|
return array;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can't remove elements from multi-dimensional arrays, since the
|
||||||
|
* result might not be rectangular.
|
||||||
|
*/
|
||||||
|
if (remove && ndim > 1)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
|
errmsg("removing elements from multidimensional arrays is not supported")));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We arrange to look up the equality function only once per series of
|
||||||
|
* calls, assuming the element type doesn't change underneath us.
|
||||||
|
*/
|
||||||
|
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
||||||
|
if (typentry == NULL ||
|
||||||
|
typentry->type_id != element_type)
|
||||||
|
{
|
||||||
|
typentry = lookup_type_cache(element_type,
|
||||||
|
TYPECACHE_EQ_OPR_FINFO);
|
||||||
|
if (!OidIsValid(typentry->eq_opr_finfo.fn_oid))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_UNDEFINED_FUNCTION),
|
||||||
|
errmsg("could not identify an equality operator for type %s",
|
||||||
|
format_type_be(element_type))));
|
||||||
|
fcinfo->flinfo->fn_extra = (void *) typentry;
|
||||||
|
}
|
||||||
|
typlen = typentry->typlen;
|
||||||
|
typbyval = typentry->typbyval;
|
||||||
|
typalign = typentry->typalign;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detoast values if they are toasted. The replacement value must be
|
||||||
|
* detoasted for insertion into the result array, while detoasting the
|
||||||
|
* search value only once saves cycles.
|
||||||
|
*/
|
||||||
|
if (typlen == -1)
|
||||||
|
{
|
||||||
|
if (!search_isnull)
|
||||||
|
search = PointerGetDatum(PG_DETOAST_DATUM(search));
|
||||||
|
if (!replace_isnull)
|
||||||
|
replace = PointerGetDatum(PG_DETOAST_DATUM(replace));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare to apply the comparison operator */
|
||||||
|
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
||||||
|
collation, NULL, NULL);
|
||||||
|
|
||||||
|
/* Allocate temporary arrays for new values */
|
||||||
|
values = (Datum *) palloc(nitems * sizeof(Datum));
|
||||||
|
nulls = (bool *) palloc(nitems * sizeof(bool));
|
||||||
|
|
||||||
|
/* Loop over source data */
|
||||||
|
arraydataptr = ARR_DATA_PTR(array);
|
||||||
|
bitmap = ARR_NULLBITMAP(array);
|
||||||
|
bitmask = 1;
|
||||||
|
hasnulls = false;
|
||||||
|
nresult = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < nitems; i++)
|
||||||
|
{
|
||||||
|
Datum elt;
|
||||||
|
bool isNull;
|
||||||
|
bool oprresult;
|
||||||
|
bool skip = false;
|
||||||
|
|
||||||
|
/* Get source element, checking for NULL */
|
||||||
|
if (bitmap && (*bitmap & bitmask) == 0)
|
||||||
|
{
|
||||||
|
isNull = true;
|
||||||
|
/* If searching for NULL, we have a match */
|
||||||
|
if (search_isnull)
|
||||||
|
{
|
||||||
|
if (remove)
|
||||||
|
{
|
||||||
|
skip = true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
else if (!replace_isnull)
|
||||||
|
{
|
||||||
|
values[nresult] = replace;
|
||||||
|
isNull = false;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
isNull = false;
|
||||||
|
elt = fetch_att(arraydataptr, typbyval, typlen);
|
||||||
|
arraydataptr = att_addlength_datum(arraydataptr, typlen, elt);
|
||||||
|
arraydataptr = (char *) att_align_nominal(arraydataptr, typalign);
|
||||||
|
|
||||||
|
if (search_isnull)
|
||||||
|
{
|
||||||
|
/* no match possible, keep element */
|
||||||
|
values[nresult] = elt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Apply the operator to the element pair
|
||||||
|
*/
|
||||||
|
locfcinfo.arg[0] = elt;
|
||||||
|
locfcinfo.arg[1] = search;
|
||||||
|
locfcinfo.argnull[0] = false;
|
||||||
|
locfcinfo.argnull[1] = false;
|
||||||
|
locfcinfo.isnull = false;
|
||||||
|
oprresult = DatumGetBool(FunctionCallInvoke(&locfcinfo));
|
||||||
|
if (!oprresult)
|
||||||
|
{
|
||||||
|
/* no match, keep element */
|
||||||
|
values[nresult] = elt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* match, so replace or delete */
|
||||||
|
changed = true;
|
||||||
|
if (remove)
|
||||||
|
skip = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
values[nresult] = replace;
|
||||||
|
isNull = replace_isnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skip)
|
||||||
|
{
|
||||||
|
nulls[nresult] = isNull;
|
||||||
|
if (isNull)
|
||||||
|
hasnulls = true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Update total result size */
|
||||||
|
nbytes = att_addlength_datum(nbytes, typlen, values[nresult]);
|
||||||
|
nbytes = att_align_nominal(nbytes, typalign);
|
||||||
|
/* check for overflow of total request */
|
||||||
|
if (!AllocSizeIsValid(nbytes))
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||||
|
errmsg("array size exceeds the maximum allowed (%d)",
|
||||||
|
(int) MaxAllocSize)));
|
||||||
|
}
|
||||||
|
nresult++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* advance bitmap pointer if any */
|
||||||
|
if (bitmap)
|
||||||
|
{
|
||||||
|
bitmask <<= 1;
|
||||||
|
if (bitmask == 0x100)
|
||||||
|
{
|
||||||
|
bitmap++;
|
||||||
|
bitmask = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If not changed just return the original array
|
||||||
|
*/
|
||||||
|
if (!changed)
|
||||||
|
{
|
||||||
|
pfree(values);
|
||||||
|
pfree(nulls);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate and initialize the result array */
|
||||||
|
if (hasnulls)
|
||||||
|
{
|
||||||
|
dataoffset = ARR_OVERHEAD_WITHNULLS(ndim, nresult);
|
||||||
|
nbytes += dataoffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataoffset = 0; /* marker for no null bitmap */
|
||||||
|
nbytes += ARR_OVERHEAD_NONULLS(ndim);
|
||||||
|
}
|
||||||
|
result = (ArrayType *) palloc0(nbytes);
|
||||||
|
SET_VARSIZE(result, nbytes);
|
||||||
|
result->ndim = ndim;
|
||||||
|
result->dataoffset = dataoffset;
|
||||||
|
result->elemtype = element_type;
|
||||||
|
memcpy(ARR_DIMS(result), ARR_DIMS(array), 2 * ndim * sizeof(int));
|
||||||
|
|
||||||
|
if (remove)
|
||||||
|
{
|
||||||
|
/* Adjust the result length */
|
||||||
|
ARR_DIMS(result)[0] = nresult;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Insert data into result array */
|
||||||
|
CopyArrayEls(result,
|
||||||
|
values, nulls, nresult,
|
||||||
|
typlen, typbyval, typalign,
|
||||||
|
false);
|
||||||
|
|
||||||
|
pfree(values);
|
||||||
|
pfree(nulls);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove any occurrences of an element from an array
|
||||||
|
*
|
||||||
|
* If used on a multi-dimensional array this will raise an error.
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
array_remove(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
ArrayType *array;
|
||||||
|
Datum search = PG_GETARG_DATUM(1);
|
||||||
|
bool search_isnull = PG_ARGISNULL(1);
|
||||||
|
|
||||||
|
if (PG_ARGISNULL(0))
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
array = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
|
|
||||||
|
array = array_replace_internal(array,
|
||||||
|
search, search_isnull,
|
||||||
|
(Datum) 0, true,
|
||||||
|
true, PG_GET_COLLATION(),
|
||||||
|
fcinfo);
|
||||||
|
PG_RETURN_ARRAYTYPE_P(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replace any occurrences of an element in an array
|
||||||
|
*/
|
||||||
|
Datum
|
||||||
|
array_replace(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
ArrayType *array;
|
||||||
|
Datum search = PG_GETARG_DATUM(1);
|
||||||
|
bool search_isnull = PG_ARGISNULL(1);
|
||||||
|
Datum replace = PG_GETARG_DATUM(2);
|
||||||
|
bool replace_isnull = PG_ARGISNULL(2);
|
||||||
|
|
||||||
|
if (PG_ARGISNULL(0))
|
||||||
|
PG_RETURN_NULL();
|
||||||
|
array = PG_GETARG_ARRAYTYPE_P(0);
|
||||||
|
|
||||||
|
array = array_replace_internal(array,
|
||||||
|
search, search_isnull,
|
||||||
|
replace, replace_isnull,
|
||||||
|
false, PG_GET_COLLATION(),
|
||||||
|
fcinfo);
|
||||||
|
PG_RETURN_ARRAYTYPE_P(array);
|
||||||
|
}
|
||||||
|
@ -53,6 +53,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 201206171
|
#define CATALOG_VERSION_NO 201207111
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -867,6 +867,10 @@ DATA(insert OID = 1286 ( array_fill PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 22
|
|||||||
DESCR("array constructor with value");
|
DESCR("array constructor with value");
|
||||||
DATA(insert OID = 2331 ( unnest PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2283 "2277" _null_ _null_ _null_ _null_ array_unnest _null_ _null_ _null_ ));
|
DATA(insert OID = 2331 ( unnest PGNSP PGUID 12 1 100 0 0 f f f f t t i 1 0 2283 "2277" _null_ _null_ _null_ _null_ array_unnest _null_ _null_ _null_ ));
|
||||||
DESCR("expand array to set of rows");
|
DESCR("expand array to set of rows");
|
||||||
|
DATA(insert OID = 3167 ( array_remove PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2277 "2277 2283" _null_ _null_ _null_ _null_ array_remove _null_ _null_ _null_ ));
|
||||||
|
DESCR("remove any occurrences of an element from an array");
|
||||||
|
DATA(insert OID = 3168 ( array_replace PGNSP PGUID 12 1 0 0 0 f f f f f f i 3 0 2277 "2277 2283 2283" _null_ _null_ _null_ _null_ array_replace _null_ _null_ _null_ ));
|
||||||
|
DESCR("replace any occurrences of an element in an array");
|
||||||
DATA(insert OID = 2333 ( array_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2283" _null_ _null_ _null_ _null_ array_agg_transfn _null_ _null_ _null_ ));
|
DATA(insert OID = 2333 ( array_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 2 0 2281 "2281 2283" _null_ _null_ _null_ _null_ array_agg_transfn _null_ _null_ _null_ ));
|
||||||
DESCR("aggregate transition function");
|
DESCR("aggregate transition function");
|
||||||
DATA(insert OID = 2334 ( array_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 2277 "2281" _null_ _null_ _null_ _null_ array_agg_finalfn _null_ _null_ _null_ ));
|
DATA(insert OID = 2334 ( array_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f f i 1 0 2277 "2281" _null_ _null_ _null_ _null_ array_agg_finalfn _null_ _null_ _null_ ));
|
||||||
|
@ -211,6 +211,8 @@ extern Datum generate_subscripts_nodir(PG_FUNCTION_ARGS);
|
|||||||
extern Datum array_fill(PG_FUNCTION_ARGS);
|
extern Datum array_fill(PG_FUNCTION_ARGS);
|
||||||
extern Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS);
|
extern Datum array_fill_with_lower_bounds(PG_FUNCTION_ARGS);
|
||||||
extern Datum array_unnest(PG_FUNCTION_ARGS);
|
extern Datum array_unnest(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum array_remove(PG_FUNCTION_ARGS);
|
||||||
|
extern Datum array_replace(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
|
extern Datum array_ref(ArrayType *array, int nSubscripts, int *indx,
|
||||||
int arraytyplen, int elmlen, bool elmbyval, char elmalign,
|
int arraytyplen, int elmlen, bool elmbyval, char elmalign,
|
||||||
|
@ -1542,6 +1542,68 @@ select unnest(array[1,2,3,null,4,null,null,5,6]::text[]);
|
|||||||
6
|
6
|
||||||
(9 rows)
|
(9 rows)
|
||||||
|
|
||||||
|
select array_remove(array[1,2,2,3], 2);
|
||||||
|
array_remove
|
||||||
|
--------------
|
||||||
|
{1,3}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_remove(array[1,2,2,3], 5);
|
||||||
|
array_remove
|
||||||
|
--------------
|
||||||
|
{1,2,2,3}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_remove(array[1,NULL,NULL,3], NULL);
|
||||||
|
array_remove
|
||||||
|
--------------
|
||||||
|
{1,3}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_remove(array['A','CC','D','C','RR'], 'RR');
|
||||||
|
array_remove
|
||||||
|
--------------
|
||||||
|
{A,CC,D,C}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed
|
||||||
|
ERROR: removing elements from multidimensional arrays is not supported
|
||||||
|
select array_replace(array[1,2,5,4],5,3);
|
||||||
|
array_replace
|
||||||
|
---------------
|
||||||
|
{1,2,3,4}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_replace(array[1,2,5,4],5,NULL);
|
||||||
|
array_replace
|
||||||
|
---------------
|
||||||
|
{1,2,NULL,4}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_replace(array[1,2,NULL,4,NULL],NULL,5);
|
||||||
|
array_replace
|
||||||
|
---------------
|
||||||
|
{1,2,5,4,5}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_replace(array['A','B','DD','B'],'B','CC');
|
||||||
|
array_replace
|
||||||
|
---------------
|
||||||
|
{A,CC,DD,CC}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_replace(array[1,NULL,3],NULL,NULL);
|
||||||
|
array_replace
|
||||||
|
---------------
|
||||||
|
{1,NULL,3}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select array_replace(array['AB',NULL,'CDE'],NULL,'12');
|
||||||
|
array_replace
|
||||||
|
---------------
|
||||||
|
{AB,12,CDE}
|
||||||
|
(1 row)
|
||||||
|
|
||||||
-- Insert/update on a column that is array of composite
|
-- Insert/update on a column that is array of composite
|
||||||
create temp table t1 (f1 int8_tbl[]);
|
create temp table t1 (f1 int8_tbl[]);
|
||||||
insert into t1 (f1[5].q1) values(42);
|
insert into t1 (f1[5].q1) values(42);
|
||||||
|
@ -432,6 +432,17 @@ select unnest(array[1,2,3,4.5]::float8[]);
|
|||||||
select unnest(array[1,2,3,4.5]::numeric[]);
|
select unnest(array[1,2,3,4.5]::numeric[]);
|
||||||
select unnest(array[1,2,3,null,4,null,null,5,6]);
|
select unnest(array[1,2,3,null,4,null,null,5,6]);
|
||||||
select unnest(array[1,2,3,null,4,null,null,5,6]::text[]);
|
select unnest(array[1,2,3,null,4,null,null,5,6]::text[]);
|
||||||
|
select array_remove(array[1,2,2,3], 2);
|
||||||
|
select array_remove(array[1,2,2,3], 5);
|
||||||
|
select array_remove(array[1,NULL,NULL,3], NULL);
|
||||||
|
select array_remove(array['A','CC','D','C','RR'], 'RR');
|
||||||
|
select array_remove('{{1,2,2},{1,4,3}}', 2); -- not allowed
|
||||||
|
select array_replace(array[1,2,5,4],5,3);
|
||||||
|
select array_replace(array[1,2,5,4],5,NULL);
|
||||||
|
select array_replace(array[1,2,NULL,4,NULL],NULL,5);
|
||||||
|
select array_replace(array['A','B','DD','B'],'B','CC');
|
||||||
|
select array_replace(array[1,NULL,3],NULL,NULL);
|
||||||
|
select array_replace(array['AB',NULL,'CDE'],NULL,'12');
|
||||||
|
|
||||||
-- Insert/update on a column that is array of composite
|
-- Insert/update on a column that is array of composite
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user