----------------------------------------------------------------------------- * array_positions : * return an array of positions of a value in an array. * * IS NOT DISTINCT FROM semantics are used for comparisons. Returns NULL when * the input array is NULL. When the value is not found in the array, returns * an empty array. * * This is not strict so we have to test for null inputs exp
| 1645 | *----------------------------------------------------------------------------- |
| 1646 | */ |
| 1647 | Datum |
| 1648 | array_positions(PG_FUNCTION_ARGS) |
| 1649 | { |
| 1650 | ArrayType *array; |
| 1651 | Oid collation = PG_GET_COLLATION(); |
| 1652 | Oid element_type; |
| 1653 | Datum searched_element, |
| 1654 | value; |
| 1655 | bool isnull; |
| 1656 | int position; |
| 1657 | TypeCacheEntry *typentry; |
| 1658 | ArrayMetaState *my_extra; |
| 1659 | bool null_search; |
| 1660 | ArrayIterator array_iterator; |
| 1661 | ArrayBuildState *astate = NULL; |
| 1662 | |
| 1663 | if (PG_ARGISNULL(0)) |
| 1664 | PG_RETURN_NULL(); |
| 1665 | |
| 1666 | array = PG_GETARG_ARRAYTYPE_P(0); |
| 1667 | element_type = ARR_ELEMTYPE(array); |
| 1668 | |
| 1669 | position = (ARR_LBOUND(array))[0] - 1; |
| 1670 | |
| 1671 | /* |
| 1672 | * We refuse to search for elements in multi-dimensional arrays, since we |
| 1673 | * have no good way to report the element's location in the array. |
| 1674 | */ |
| 1675 | if (ARR_NDIM(array) > 1) |
| 1676 | ereport(ERROR, |
| 1677 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 1678 | errmsg("searching for elements in multidimensional arrays is not supported"))); |
| 1679 | |
| 1680 | astate = initArrayResult(INT4OID, CurrentMemoryContext, false); |
| 1681 | |
| 1682 | if (PG_ARGISNULL(1)) |
| 1683 | { |
| 1684 | /* fast return when the array doesn't have nulls */ |
| 1685 | if (!array_contains_nulls(array)) |
| 1686 | PG_RETURN_DATUM(makeArrayResult(astate, CurrentMemoryContext)); |
| 1687 | searched_element = (Datum) 0; |
| 1688 | null_search = true; |
| 1689 | } |
| 1690 | else |
| 1691 | { |
| 1692 | searched_element = PG_GETARG_DATUM(1); |
| 1693 | null_search = false; |
| 1694 | } |
| 1695 | |
| 1696 | /* |
| 1697 | * We arrange to look up type info for array_create_iterator only once per |
| 1698 | * series of calls, assuming the element type doesn't change underneath |
| 1699 | * us. |
| 1700 | */ |
| 1701 | my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; |
| 1702 | if (my_extra == NULL) |
| 1703 | { |
| 1704 | fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, |
nothing calls this directly
no test coverage detected