diff --git a/doc/src/sgml/array.sgml b/doc/src/sgml/array.sgml index bb4657e..35de925 100644 *** a/doc/src/sgml/array.sgml --- b/doc/src/sgml/array.sgml *************** INSERT ... VALUES (E'{"\\\\","\\""}'); *** 706,709 **** --- 706,817 ---- + + Multiset Support + + + array + multiset + + + + Multiset is another collection data type specified in the SQL standard. + It is similar to arrays, but the order of elements is irrelevant. + PostgreSQL doesn't support distinct multiset + data type, but has serveral functions and operators based on array types. + + + + MEMBER OF and SUBMULTISET OF operators returns + true when the element or subset is contained by the collection. + MEMBER OF is exactly same as = ANY operator. + On the other hand, SUBMULTISET OF differs from <@ + because it returns true only if the container have equal or more elements + the containded collection. + + SELECT 2 MEMBER OF ARRAY[1,2], 2 = ANY(ARRAY[1,2]); + ?column? | ?column? + ----------+---------- + t | t + (1 row) + + SELECT ARRAY[1,1] SUBMULTISET OF ARRAY[1,2], + ARRAY[1,1] <@ ARRAY[1,2]; + submultiset_of | ?column? + ----------------+---------- + f | t + (1 row) + + + + + IS A SET operator returns true when the collection has + no duplicated values. A collection that has two or more NULLs are not + considered as a set. + + SELECT ARRAY[1,2,3] IS A SET, + ARRAY[1,1,2] IS A SET, + ARRAY[1,NULL,NULL] IS A SET; + + is_a_set | is_a_set | is_a_set + ----------+----------+---------- + t | f | f + (1 row) + + set function returns a collection of unique elements + as like as DISTINCT clause in a query. + + SELECT set(ARRAY[1,2,NULL,2,NULL,1,2]); + set + ------------ + {1,2,NULL} + (1 row) + + + + + MULTISET EXCEPT, MULTISET INTERSECT, and + MULTISET UNION operator combine two collections as like as + set operations in a query (see ). + They can have optional ALL or DISTINCT options. + If DISTINCT is specified or not specified, they eliminates + duplicated elements before the set operations. + + SELECT ARRAY[2,NULL,1,2,NULL] MULTISET UNION ARRAY[2,NULL], + ARRAY[2,NULL,1,2,NULL] MULTISET INTERSECT ARRAY[2,NULL], + ARRAY[2,NULL,1,2,NULL] MULTISET EXCEPT ARRAY[2,NULL]; + multiset_union | multiset_intersect | multiset_except + ----------------+--------------------+----------------- + {1,2,NULL} | {2,NULL} | {1} + (1 row) + + SELECT ARRAY[2,NULL,1,2,NULL] MULTISET UNION ALL ARRAY[2,NULL], + ARRAY[2,NULL,1,2,NULL] MULTISET INTERSECT ALL ARRAY[2,NULL], + ARRAY[2,NULL,1,2,NULL] MULTISET EXCEPT ALL ARRAY[2,NULL]; + multiset_union | multiset_intersect | multiset_except + --------------------------+--------------------+----------------- + {2,NULL,1,2,NULL,2,NULL} | {2,NULL} | {1,2,NULL} + (1 row) + + + + + + Since multisets are actually arrays, some of operators and functions still + treats them as arrays. The following example shows two collections are + sub-multiset of each other, but not equal with = operator + because they are arrays in fact; they have the same set of elements, but + differ in the order of elements. + + SELECT a SUBMULTISET OF b, b SUBMULTISET OF a, a = b + FROM (VALUES(ARRAY[1,2], ARRAY[2,1])) t(a, b); + submultiset_of | submultiset_of | ?column? + ----------------+----------------+---------- + t | t | f + (1 row) + + + + + diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 04769f1..aae831c 100644 *** a/doc/src/sgml/func.sgml --- b/doc/src/sgml/func.sgml *************** SELECT NULLIF(value, '(none)') ... *** 10196,10201 **** --- 10196,10311 ---- + shows the multiset operators + available for array types. See for more details + and limitations. + + + + Multiset Operators + + + + Operator + Description + Example + Result + + + + + + + IS A SET + + IS [ NOT ] A SET + + has only unique elements + ARRAY[1,2,3] IS A SET + t + + + + + + MEMBER OF + + [ NOT ] MEMBER OF + + is a member of + 2 MEMBER OF ARRAY[1,2,3] + t + + + + + + SUBMULTISET OF + + [ NOT ] SUBMULTISET OF + + is a subset of + ARRAY[1,2] SUBMULTISET OF ARRAY[3,2,1] + t + + + + + + MULTISET EXCEPT + + MULTISET EXCEPT [ ALL | DISTINCT ] + + subtraction of + ARRAY[1,1,2] MULTISET EXCEPT ARRAY[1,3] + {2} + + + + + + MULTISET INTERSECT + + MULTISET INTERSECT [ ALL | DISTINCT ] + + intersection of + ARRAY[1,1,2] MULTISET INTERSECT ARRAY[1,3] + {1} + + + + + + MULTISET UNION + + MULTISET UNION [ ALL | DISTINCT ] + + union of + ARRAY[1,1,2] MULTISET UNION ARRAY[1,3] + {1,2,3} + + + +
+ + + In IS A SET, MEMBER OF, SUBMULTISET OF, + MULTISET INTERSECT, MULTISET UNION, and + MULTISET EXCEPT operators, the order of elements in input array + are ignored. They treats the input as a multiset (or bag) rather than an array. + Dimension and lower bound of the array don't affect the result at all. + + + + SUBMULTISET OF treats NULLs in input arrays as unknown values. + For example, ARRAY[1, 2] SUBMULTISET OF ARRAY[1, NULL] returns + NULL. It means we cannot determine whether they matches or not because the + NULL in the right hand argument might be 2 or other value. On the other hand, + ARRAY[1, 2] SUBMULTISET OF ARRAY[3, NULL] returns false because + there are NULL values less than unmatched values. + + + shows the functions available for use with array types. See for more information and examples of the use of these functions. *************** SELECT NULLIF(value, '(none)') ... *** 10226,10240 **** --- 10336,10362 ---- array_prepend + array_sort + + array_to_string array_upper + cardinality + + string_to_array + set + + + trim_array + + unnest *************** SELECT NULLIF(value, '(none)') ... *** 10344,10349 **** --- 10466,10482 ---- + array_sort(anyarray) + + + anyarray + sort elements in an array in ascending order + array_sort(ARRAY[3,2,NULL,1]) + {1,2,3,NULL} + + + + array_to_string(anyarray, text , text) *************** SELECT NULLIF(value, '(none)') ... *** 10379,10384 **** --- 10512,10550 ---- + cardinality(anyarray) + + + int + returns the number of elements in an array + cardinality(ARRAY[1,2,3]) + 3 + + + + + set(anyarray) + + + anyarray + remove duplicated elements in an array + set(ARRAY[1,3,2,3,NULL,1,NULL]) + {1,2,3,NULL} + + + + + trim_array(anyarray) + + + anyarray + remove elements at end of an array + trim_array(ARRAY[1, 2, 3], 2) + {1} + + + + unnest(anyarray) *************** SELECT NULLIF(value, '(none)') ... *** 10421,10428 **** See also about the aggregate ! function array_agg for use with arrays. --- 10587,10601 ---- + In array_sort, set, and trim_array + functions, input arrays are always flattened into one-dimensional arrays. + In addition, the lower bounds of the arrays are adjusted to 1. + + + See also about the aggregate ! function array_agg, collect, ! fusion, and intersection for use with arrays. *************** SELECT NULLIF(value, '(none)') ... *** 10468,10474 **** array_agg(expression) ! any array of the argument type --- 10641,10647 ---- array_agg(expression) ! any non-array array of the argument type *************** SELECT NULLIF(value, '(none)') ... *** 10568,10573 **** --- 10741,10762 ---- + collect + + collect(expression) + + + any non-array + + + array of the argument type + + an alias for array_agg + + + + + count count(*) *************** SELECT NULLIF(value, '(none)') ... *** 10606,10611 **** --- 10795,10832 ---- + fusion + + fusion(expression) + + + any array + + + same as argument type + + concatenation of input arrays + + + + + + intersection + + intersection(expression) + + + any array + + + same as argument type + + intersection of input arrays + + + + + max max(expression)