move array functions to a separate file
authorRogan Hamby <rhamby@esilibrary.com>
Thu, 5 Sep 2019 13:51:44 +0000 (09:51 -0400)
committerRogan Hamby <rhamby@esilibrary.com>
Thu, 5 Sep 2019 13:51:44 +0000 (09:51 -0400)
sql/base/21-fixed-fields.sql
sql/base/22-anyarray.sql [new file with mode: 0644]

index 8911b4e..fe9c3d0 100644 (file)
@@ -317,73 +317,6 @@ BEGIN
 END;
 $func$ LANGUAGE PLPGSQL;
 
-DROP AGGREGATE IF EXISTS anyarray_agg(anyarray);
-CREATE AGGREGATE anyarray_agg(anyarray) (
-        SFUNC = migration_tools.anyarray_agg_statefunc,
-        STYPE = anyarray
-);
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_agg_statefunc(anyarray, anyarray);
-CREATE FUNCTION migration_tools.anyarray_agg_statefunc(state anyarray, value anyarray)
-        RETURNS anyarray AS
-$BODY$
-        SELECT array_cat($1, $2)
-$BODY$
-        LANGUAGE sql IMMUTABLE;
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_sort(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_sort(with_array anyarray)
-    RETURNS anyarray AS
-$BODY$
-    DECLARE
-        return_array with_array%TYPE := '{}';
-    BEGIN
-        SELECT ARRAY_AGG(sorted_vals.val) AS array_value
-        FROM
-            (   SELECT UNNEST(with_array) AS val
-                ORDER BY val
-            ) AS sorted_vals INTO return_array;
-        RETURN return_array;
-    END;
-$BODY$ LANGUAGE plpgsql;
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_uniq(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_uniq(with_array anyarray)
-    RETURNS anyarray AS
-$BODY$
-    DECLARE
-        -- The variable used to track iteration over "with_array".
-        loop_offset integer;
-
-        -- The array to be returned by this function.
-        return_array with_array%TYPE := '{}';
-    BEGIN
-        IF with_array IS NULL THEN
-            return NULL;
-        END IF;
-
-        IF with_array = '{}' THEN
-            return return_array;
-        END IF;
-
-        -- Iterate over each element in "concat_array".
-        FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
-            IF with_array[loop_offset] IS NULL THEN
-                IF NOT EXISTS
-                    ( SELECT 1 FROM UNNEST(return_array) AS s(a)
-                    WHERE a IS NULL )
-                THEN return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
-                END IF;
-            -- When an array contains a NULL value, ANY() returns NULL instead of FALSE...
-            ELSEIF NOT(with_array[loop_offset] = ANY(return_array)) OR NOT(NULL IS DISTINCT FROM (with_array[loop_offset] = ANY(return_array))) THEN
-                return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
-            END IF;
-        END LOOP;
-
-    RETURN return_array;
- END;
-$BODY$ LANGUAGE plpgsql;
-
 DROP FUNCTION IF EXISTS migration_tools.modify_staged_fixed_fields (BIGINT,TEXT);
 CREATE OR REPLACE FUNCTION migration_tools.modify_staged_fixed_fields (bib_id BIGINT, xcode TEXT)
  RETURNS BOOLEAN
@@ -414,7 +347,7 @@ BEGIN
        ELSE
                ysrform_exclude := '';
        END IF;
-    SELECT modify_fixed_fields(marc,xcode,xitype,xiform,xphy,xphyv,xphyp,xbiblevel,yiform_exclude,ysrform_exclude) FROM biblio_record_entry_legacy WHERE id = bib_id INTO r;
+    SELECT migration_tools.modify_fixed_fields(marc,xcode,xitype,xiform,xphy,xphyv,xphyp,xbiblevel,yiform_exclude,ysrform_exclude) FROM biblio_record_entry_legacy WHERE id = bib_id INTO r;
     UPDATE biblio_record_entry_legacy SET marc = r WHERE id = bib_id;
     RETURN TRUE;
 END;
@@ -540,373 +473,3 @@ my $zzs_str;
 return $marc->as_xml_record;
 $function$;
 
-DROP FUNCTION IF EXISTS migration_tools.anyarray_agg_statefunc(anyarray, anyarray);
-CREATE FUNCTION migration_tools.anyarray_agg_statefunc(state anyarray, value anyarray)
-       RETURNS anyarray AS
-$BODY$
-       SELECT array_cat($1, $2)
-$BODY$
-       LANGUAGE sql IMMUTABLE;
-
-DROP AGGREGATE IF EXISTS anyarray_agg(anyarray);
-CREATE AGGREGATE anyarray_agg(anyarray) (
-       SFUNC = migration_tools.anyarray_agg_statefunc,
-       STYPE = anyarray
-);
-
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_concat(anyarray, anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat(with_array anyarray, concat_array anyarray)
-       RETURNS anyarray AS
-$BODY$
-       DECLARE
-               -- The variable used to track iteration over "with_array".
-               loop_offset integer;
-
-               -- The array to be returned by this function.
-               return_array with_array%TYPE;
-       BEGIN
-               IF with_array IS NULL THEN
-                       RETURN concat_array;
-               ELSEIF concat_array IS NULL THEN
-                       RETURN with_array;
-               END IF;
-
-               -- Add all items in "with_array" to "return_array".
-               return_array = with_array;
-
-               -- Iterate over each element in "concat_array", appending it to "return_array".
-               FOR loop_offset IN ARRAY_LOWER(concat_array, 1)..ARRAY_UPPER(concat_array, 1) LOOP
-                       return_array = ARRAY_APPEND(return_array, concat_array[loop_offset]);
-               END LOOP;
-
-               RETURN return_array;
-       END;
-$BODY$ LANGUAGE plpgsql;
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_concat(anyarray, anynonarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat(with_array anyarray, concat_element anynonarray)
-       RETURNS anyarray AS
-$BODY$
-       BEGIN
-               RETURN ANYARRAY_CONCAT(with_array, ARRAY[concat_element]);
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_concat_uniq(anyarray, anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat_uniq(with_array anyarray, concat_array anyarray)
-       RETURNS anyarray AS
-$BODY$
-       DECLARE
-               -- The variable used to track iteration over "with_array".
-               loop_offset integer;
-
-               -- The array to be returned by this function.
-               return_array with_array%TYPE;
-       BEGIN
-               IF with_array IS NULL THEN
-                       RETURN concat_array;
-               ELSEIF concat_array IS NULL THEN
-                       RETURN with_array;
-               END IF;
-
-               -- Add all items in "with_array" to "return_array".
-               return_array = with_array;
-
-               -- Iterate over each element in "concat_array".
-               FOR loop_offset IN ARRAY_LOWER(concat_array, 1)..ARRAY_UPPER(concat_array, 1) LOOP
-                       IF NOT concat_array[loop_offset] = ANY(return_array) THEN
-                               return_array = ARRAY_APPEND(return_array, concat_array[loop_offset]);
-                       END IF;
-               END LOOP;
-
-               RETURN return_array;
-       END;
-$BODY$ LANGUAGE plpgsql;
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_concat_uniq(anyarray, anynonarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat_uniq(with_array anyarray, concat_element anynonarray)
-       RETURNS anyarray AS
-$BODY$
-       BEGIN
-               RETURN ANYARRAY_CONCAT_UNIQ(with_array, ARRAY[concat_element]);
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_diff(anyarray, anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_diff(with_array anyarray, against_array anyarray)
-       RETURNS anyarray AS
-$BODY$
-       DECLARE
-               -- The variable used to track iteration over "with_array".
-               loop_offset integer;
-               
-               -- The array to be returned by this function.
-               return_array with_array%TYPE := '{}';
-       BEGIN
-               IF with_array IS NULL THEN
-                       RETURN against_array;
-               ELSEIF against_array IS NULL THEN
-                       RETURN with_array;
-               END IF;
-
-               -- Iterate over with_array.
-               FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
-                       IF NOT with_array[loop_offset] = ANY(against_array) THEN
-                               return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
-                       END IF;
-               END LOOP;
-
-               -- Iterate over against_array.
-               FOR loop_offset IN ARRAY_LOWER(against_array, 1)..ARRAY_UPPER(against_array, 1) LOOP
-                       IF NOT against_array[loop_offset] = ANY(with_array) THEN
-                               return_array = ARRAY_APPEND(return_array, against_array[loop_offset]);
-                       END IF;
-               END LOOP;
-
-               RETURN return_array;
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_diff_uniq(anyarray, anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_diff_uniq(with_array anyarray, against_array anyarray)
-       RETURNS anyarray AS
-$BODY$
-       DECLARE
-               -- The variable used to track iteration over "with_array".
-               loop_offset integer;
-               
-               -- The array to be returned by this function.
-               return_array with_array%TYPE := '{}';
-       BEGIN
-               IF with_array IS NULL THEN
-                       RETURN against_array;
-               ELSEIF against_array IS NULL THEN
-                       RETURN with_array;
-               END IF;
-
-               -- Iterate over with_array.
-               FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
-                       RAISE NOTICE '% %', with_array[loop_offset], return_array;
-                       IF (NOT with_array[loop_offset] = ANY(against_array)) AND (NOT with_array[loop_offset] = ANY(return_array)) THEN
-                               return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
-                       END IF;
-               END LOOP;
-
-               -- Iterate over against_array.
-               FOR loop_offset IN ARRAY_LOWER(against_array, 1)..ARRAY_UPPER(against_array, 1) LOOP
-                       RAISE NOTICE '% %', against_array[loop_offset], return_array;
-                       IF (NOT against_array[loop_offset] = ANY(with_array)) AND (NOT against_array[loop_offset] = ANY(return_array)) THEN
-                               return_array = ARRAY_APPEND(return_array, against_array[loop_offset]);
-                       END IF;
-               END LOOP;
-
-               RETURN return_array;
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_enumerate(anyarray);
-CREATE FUNCTION migration_tools.anyarray_enumerate(anyarray)
-       RETURNS TABLE (index bigint, value anyelement) AS
-$$
-       SELECT
-               row_number() OVER (),
-               value
-       FROM (
-               SELECT unnest($1) AS value
-       ) AS unnested
-$$
-       LANGUAGE sql IMMUTABLE;
-COMMENT ON FUNCTION migration_tools.anyarray_enumerate(anyarray) IS '
-Unnests the array along with the indices of each element.
-
-*index* (bigint) is the index of the element within the array starting at 1.
-
-*value* (anyelement) is the element from the array.
-
-NOTE: Multi-dimensional arrays will be flattened as they are with *unnest()*. 
-';
-DROP FUNCTION IF EXISTS migration_tools.anyarray_is_array(anyelement);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_is_array(anyelement)
-       RETURNS boolean AS
-$BODY$
-       BEGIN
-               -- TODO: Is there a more "elegant" / less hacky of accomplishing
-               -- this?
-
-               -- If the following function call throws an exception, we know the
-               -- element is not an array. If the call succeeds, then it must be
-               -- an array.
-               EXECUTE FORMAT('WITH a AS (SELECT %L::TEXT[] AS val) SELECT ARRAY_DIMS(a.val) FROM a', $1);
-               RETURN TRUE;
-       EXCEPTION WHEN
-             SQLSTATE '42804' -- Unknown data-type passed
-             OR SQLSTATE '42883' -- Function doesn't exist
-             OR SQLSTATE '22P02' -- Unable to cast to an array
-       THEN
-               RETURN FALSE;
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_numeric_only(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_numeric_only(anyarray)
-        RETURNS anyarray AS
-$BODY$
-        SELECT ARRAY(
-                SELECT
-                        array_values.array_value
-                FROM
-                        (
-                                SELECT UNNEST($1) AS array_value
-                        ) AS array_values
-                WHERE
-                        array_values.array_value::TEXT ~ '^\d+(\.\d+)?$'
-        )
-$BODY$ LANGUAGE sql IMMUTABLE;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_ranges(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_ranges(from_array anyarray)
-       RETURNS SETOF text[] AS
-$BODY$
-       BEGIN
-               RETURN QUERY SELECT
-                               ARRAY_AGG(consolidated_values.consolidated_range) AS ranges
-                       FROM
-                               (
-                                       SELECT
-                                               (CASE WHEN COUNT(*) > 1 THEN
-                                                       MIN(unconsolidated_values.array_value)::text || '-' || MAX(unconsolidated_values.array_value)::text
-                                               ELSE
-                                                       MIN(unconsolidated_values.array_value)::text
-                                               END) AS consolidated_range
-                                       FROM
-                                               (
-                                                       SELECT
-                                                               array_values.array_value,
-                                                               ROW_NUMBER() OVER (ORDER BY array_values.array_value) - array_values.array_value AS consolidation_group
-                                                       FROM
-                                                               (
-                                                                       SELECT
-                                                                               UNNEST(from_array) AS array_value
-                                                               ) AS array_values
-                                                       ORDER BY
-                                                               array_values.array_value
-                                               ) AS unconsolidated_values
-                                       GROUP BY
-                                               unconsolidated_values.consolidation_group
-                                       ORDER BY
-                                               MIN(unconsolidated_values.array_value)
-                               ) AS consolidated_values
-               ;
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_remove_null(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_remove_null(from_array anyarray)
-        RETURNS anyarray AS
-$BODY$
-        DECLARE
-                -- The variable used to track iteration over "from_array".
-                loop_offset integer;
-
-                -- The array to be returned by this function.
-                return_array from_array%TYPE;
-        BEGIN
-                -- Iterate over each element in "from_array".
-                FOR loop_offset IN ARRAY_LOWER(from_array, 1)..ARRAY_UPPER(from_array, 1) LOOP
-                        IF from_array[loop_offset] IS NOT NULL THEN -- If NULL, will omit from "return_array".
-                                return_array = ARRAY_APPEND(return_array, from_array[loop_offset]);
-                        END IF;
-                END LOOP;
-
-                RETURN return_array;
-        END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_remove(anyarray, anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_remove(from_array anyarray, remove_array anyarray)
-        RETURNS anyarray AS
-$BODY$
-        DECLARE
-                -- The variable used to track iteration over "from_array".
-                loop_offset integer;
-
-
-                -- The array to be returned by this function.
-                return_array from_array%TYPE := '{}';
-        BEGIN
-                -- If either argument is NULL, there is nothing to do.
-                IF from_array IS NULL OR remove_array IS NULL THEN
-                        RETURN from_array;
-                END IF;
-
-                -- Iterate over each element in "from_array".
-                FOR loop_offset IN ARRAY_LOWER(from_array, 1)..ARRAY_UPPER(from_array, 1) LOOP
-                        -- If the element being iterated over is in "remove_array",
-                        -- do not append it to "return_array".
-                        IF (from_array[loop_offset] = ANY(remove_array)) IS DISTINCT FROM TRUE THEN
-                                return_array = ARRAY_APPEND(return_array, from_array[loop_offset]);
-                        END IF;
-                END LOOP;
-
-
-                RETURN return_array;
-        END;
-$BODY$ LANGUAGE plpgsql;
-
-
-DROP FUNCTION IF EXISTS migration_tools.anyarray_remove(anyarray, anynonarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_remove(from_array anyarray, remove_element anynonarray)
-        RETURNS anyarray AS
-$BODY$
-        BEGIN
-                RETURN ANYARRAY_REMOVE(from_array, ARRAY[remove_element]);
-        END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_sort(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_sort(with_array anyarray)
-       RETURNS SETOF anyarray AS
-$BODY$
-       BEGIN
-               RETURN QUERY SELECT 
-                       ARRAY_AGG(sorted_vals.val) AS array_value
-               FROM
-                       (
-                               SELECT
-                                       UNNEST(with_array) AS val
-                               ORDER BY
-                                       val
-                       ) AS sorted_vals
-               ;
-       END;
-$BODY$ LANGUAGE plpgsql;
-DROP FUNCTION IF EXISTS migration_tools.anyarray_uniq(anyarray);
-CREATE OR REPLACE FUNCTION migration_tools.anyarray_uniq(with_array anyarray)
-       RETURNS anyarray AS
-$BODY$
-       DECLARE
-               -- The variable used to track iteration over "with_array".
-               loop_offset integer;
-
-               -- The array to be returned by this function.
-               return_array with_array%TYPE := '{}';
-       BEGIN
-               IF with_array IS NULL THEN
-                       return NULL;
-               END IF;
-               
-               IF with_array = '{}' THEN
-                   return return_array;
-               END IF;
-
-               -- Iterate over each element in "concat_array".
-               FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
-                       IF with_array[loop_offset] IS NULL THEN
-                               IF NOT EXISTS(
-                                       SELECT 1 
-                                       FROM UNNEST(return_array) AS s(a)
-                                       WHERE a IS NULL
-                               ) THEN
-                                       return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
-                               END IF;
-                       -- When an array contains a NULL value, ANY() returns NULL instead of FALSE...
-                       ELSEIF NOT(with_array[loop_offset] = ANY(return_array)) OR NOT(NULL IS DISTINCT FROM (with_array[loop_offset] = ANY(return_array))) THEN
-                               return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
-                       END IF;
-               END LOOP;
-
-       RETURN return_array;
- END;
-$BODY$ LANGUAGE plpgsql;
diff --git a/sql/base/22-anyarray.sql b/sql/base/22-anyarray.sql
new file mode 100644 (file)
index 0000000..c50b2dc
--- /dev/null
@@ -0,0 +1,366 @@
+CREATE FUNCTION migration_tools.anyarray_agg_statefunc(state anyarray, value anyarray)
+        RETURNS anyarray AS
+$BODY$
+        SELECT array_cat($1, $2)
+$BODY$
+        LANGUAGE sql IMMUTABLE;
+
+DROP AGGREGATE IF EXISTS anyarray_agg(anyarray);
+CREATE AGGREGATE anyarray_agg(anyarray) (
+    SFUNC = migration_tools.anyarray_agg_statefunc,
+    STYPE = anyarray
+);
+
+DROP FUNCTION IF EXISTS migration_tools.anyarray_sort(anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_sort(with_array anyarray)
+    RETURNS anyarray AS
+$BODY$
+    DECLARE
+        return_array with_array%TYPE := '{}';
+    BEGIN
+        SELECT ARRAY_AGG(sorted_vals.val) AS array_value
+        FROM
+            (   SELECT UNNEST(with_array) AS val
+                ORDER BY val
+            ) AS sorted_vals INTO return_array;
+        RETURN return_array;
+    END;
+$BODY$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS migration_tools.anyarray_uniq(anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_uniq(with_array anyarray)
+    RETURNS anyarray AS
+$BODY$
+    DECLARE
+        -- The variable used to track iteration over "with_array".
+        loop_offset integer;
+
+        -- The array to be returned by this function.
+        return_array with_array%TYPE := '{}';
+    BEGIN
+        IF with_array IS NULL THEN
+            return NULL;
+        END IF;
+
+        IF with_array = '{}' THEN
+            return return_array;
+        END IF;
+
+        -- Iterate over each element in "concat_array".
+        FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
+            IF with_array[loop_offset] IS NULL THEN
+                IF NOT EXISTS
+                    ( SELECT 1 FROM UNNEST(return_array) AS s(a)
+                    WHERE a IS NULL )
+                THEN return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
+                END IF;
+            -- When an array contains a NULL value, ANY() returns NULL instead of FALSE...
+            ELSEIF NOT(with_array[loop_offset] = ANY(return_array)) OR NOT(NULL IS DISTINCT FROM (with_array[loop_offset] = ANY(return_array))) THEN
+                return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
+            END IF;
+        END LOOP;
+
+    RETURN return_array;
+ END;
+$BODY$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS migration_tools.anyarray_concat(anyarray, anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat(with_array anyarray, concat_array anyarray)
+       RETURNS anyarray AS
+$BODY$
+       DECLARE
+               -- The variable used to track iteration over "with_array".
+               loop_offset integer;
+
+               -- The array to be returned by this function.
+               return_array with_array%TYPE;
+       BEGIN
+               IF with_array IS NULL THEN
+                       RETURN concat_array;
+               ELSEIF concat_array IS NULL THEN
+                       RETURN with_array;
+               END IF;
+
+               -- Add all items in "with_array" to "return_array".
+               return_array = with_array;
+
+               -- Iterate over each element in "concat_array", appending it to "return_array".
+               FOR loop_offset IN ARRAY_LOWER(concat_array, 1)..ARRAY_UPPER(concat_array, 1) LOOP
+                       return_array = ARRAY_APPEND(return_array, concat_array[loop_offset]);
+               END LOOP;
+
+               RETURN return_array;
+       END;
+$BODY$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS migration_tools.anyarray_concat(anyarray, anynonarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat(with_array anyarray, concat_element anynonarray)
+       RETURNS anyarray AS
+$BODY$
+       BEGIN
+               RETURN ANYARRAY_CONCAT(with_array, ARRAY[concat_element]);
+       END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_concat_uniq(anyarray, anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat_uniq(with_array anyarray, concat_array anyarray)
+       RETURNS anyarray AS
+$BODY$
+       DECLARE
+               -- The variable used to track iteration over "with_array".
+               loop_offset integer;
+
+               -- The array to be returned by this function.
+               return_array with_array%TYPE;
+       BEGIN
+               IF with_array IS NULL THEN
+                       RETURN concat_array;
+               ELSEIF concat_array IS NULL THEN
+                       RETURN with_array;
+               END IF;
+
+               -- Add all items in "with_array" to "return_array".
+               return_array = with_array;
+
+               -- Iterate over each element in "concat_array".
+               FOR loop_offset IN ARRAY_LOWER(concat_array, 1)..ARRAY_UPPER(concat_array, 1) LOOP
+                       IF NOT concat_array[loop_offset] = ANY(return_array) THEN
+                               return_array = ARRAY_APPEND(return_array, concat_array[loop_offset]);
+                       END IF;
+               END LOOP;
+
+               RETURN return_array;
+       END;
+$BODY$ LANGUAGE plpgsql;
+
+DROP FUNCTION IF EXISTS migration_tools.anyarray_concat_uniq(anyarray, anynonarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_concat_uniq(with_array anyarray, concat_element anynonarray)
+       RETURNS anyarray AS
+$BODY$
+       BEGIN
+               RETURN ANYARRAY_CONCAT_UNIQ(with_array, ARRAY[concat_element]);
+       END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_diff(anyarray, anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_diff(with_array anyarray, against_array anyarray)
+       RETURNS anyarray AS
+$BODY$
+       DECLARE
+               -- The variable used to track iteration over "with_array".
+               loop_offset integer;
+               
+               -- The array to be returned by this function.
+               return_array with_array%TYPE := '{}';
+       BEGIN
+               IF with_array IS NULL THEN
+                       RETURN against_array;
+               ELSEIF against_array IS NULL THEN
+                       RETURN with_array;
+               END IF;
+
+               -- Iterate over with_array.
+               FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
+                       IF NOT with_array[loop_offset] = ANY(against_array) THEN
+                               return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
+                       END IF;
+               END LOOP;
+
+               -- Iterate over against_array.
+               FOR loop_offset IN ARRAY_LOWER(against_array, 1)..ARRAY_UPPER(against_array, 1) LOOP
+                       IF NOT against_array[loop_offset] = ANY(with_array) THEN
+                               return_array = ARRAY_APPEND(return_array, against_array[loop_offset]);
+                       END IF;
+               END LOOP;
+
+               RETURN return_array;
+       END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_diff_uniq(anyarray, anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_diff_uniq(with_array anyarray, against_array anyarray)
+       RETURNS anyarray AS
+$BODY$
+       DECLARE
+               -- The variable used to track iteration over "with_array".
+               loop_offset integer;
+               
+               -- The array to be returned by this function.
+               return_array with_array%TYPE := '{}';
+       BEGIN
+               IF with_array IS NULL THEN
+                       RETURN against_array;
+               ELSEIF against_array IS NULL THEN
+                       RETURN with_array;
+               END IF;
+
+               -- Iterate over with_array.
+               FOR loop_offset IN ARRAY_LOWER(with_array, 1)..ARRAY_UPPER(with_array, 1) LOOP
+                       RAISE NOTICE '% %', with_array[loop_offset], return_array;
+                       IF (NOT with_array[loop_offset] = ANY(against_array)) AND (NOT with_array[loop_offset] = ANY(return_array)) THEN
+                               return_array = ARRAY_APPEND(return_array, with_array[loop_offset]);
+                       END IF;
+               END LOOP;
+
+               -- Iterate over against_array.
+               FOR loop_offset IN ARRAY_LOWER(against_array, 1)..ARRAY_UPPER(against_array, 1) LOOP
+                       RAISE NOTICE '% %', against_array[loop_offset], return_array;
+                       IF (NOT against_array[loop_offset] = ANY(with_array)) AND (NOT against_array[loop_offset] = ANY(return_array)) THEN
+                               return_array = ARRAY_APPEND(return_array, against_array[loop_offset]);
+                       END IF;
+               END LOOP;
+
+               RETURN return_array;
+       END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_enumerate(anyarray);
+CREATE FUNCTION migration_tools.anyarray_enumerate(anyarray)
+       RETURNS TABLE (index bigint, value anyelement) AS
+$$
+       SELECT
+               row_number() OVER (),
+               value
+       FROM (
+               SELECT unnest($1) AS value
+       ) AS unnested
+$$
+       LANGUAGE sql IMMUTABLE;
+COMMENT ON FUNCTION migration_tools.anyarray_enumerate(anyarray) IS '
+Unnests the array along with the indices of each element.
+
+*index* (bigint) is the index of the element within the array starting at 1.
+
+*value* (anyelement) is the element from the array.
+
+NOTE: Multi-dimensional arrays will be flattened as they are with *unnest()*. 
+';
+DROP FUNCTION IF EXISTS migration_tools.anyarray_is_array(anyelement);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_is_array(anyelement)
+       RETURNS boolean AS
+$BODY$
+       BEGIN
+               -- TODO: Is there a more "elegant" / less hacky of accomplishing
+               -- this?
+
+               -- If the following function call throws an exception, we know the
+               -- element is not an array. If the call succeeds, then it must be
+               -- an array.
+               EXECUTE FORMAT('WITH a AS (SELECT %L::TEXT[] AS val) SELECT ARRAY_DIMS(a.val) FROM a', $1);
+               RETURN TRUE;
+       EXCEPTION WHEN
+             SQLSTATE '42804' -- Unknown data-type passed
+             OR SQLSTATE '42883' -- Function doesn't exist
+             OR SQLSTATE '22P02' -- Unable to cast to an array
+       THEN
+               RETURN FALSE;
+       END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_numeric_only(anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_numeric_only(anyarray)
+        RETURNS anyarray AS
+$BODY$
+        SELECT ARRAY(
+                SELECT
+                        array_values.array_value
+                FROM
+                        (
+                                SELECT UNNEST($1) AS array_value
+                        ) AS array_values
+                WHERE
+                        array_values.array_value::TEXT ~ '^\d+(\.\d+)?$'
+        )
+$BODY$ LANGUAGE sql IMMUTABLE;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_ranges(anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_ranges(from_array anyarray)
+       RETURNS SETOF text[] AS
+$BODY$
+       BEGIN
+               RETURN QUERY SELECT
+                               ARRAY_AGG(consolidated_values.consolidated_range) AS ranges
+                       FROM
+                               (
+                                       SELECT
+                                               (CASE WHEN COUNT(*) > 1 THEN
+                                                       MIN(unconsolidated_values.array_value)::text || '-' || MAX(unconsolidated_values.array_value)::text
+                                               ELSE
+                                                       MIN(unconsolidated_values.array_value)::text
+                                               END) AS consolidated_range
+                                       FROM
+                                               (
+                                                       SELECT
+                                                               array_values.array_value,
+                                                               ROW_NUMBER() OVER (ORDER BY array_values.array_value) - array_values.array_value AS consolidation_group
+                                                       FROM
+                                                               (
+                                                                       SELECT
+                                                                               UNNEST(from_array) AS array_value
+                                                               ) AS array_values
+                                                       ORDER BY
+                                                               array_values.array_value
+                                               ) AS unconsolidated_values
+                                       GROUP BY
+                                               unconsolidated_values.consolidation_group
+                                       ORDER BY
+                                               MIN(unconsolidated_values.array_value)
+                               ) AS consolidated_values
+               ;
+       END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_remove_null(anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_remove_null(from_array anyarray)
+        RETURNS anyarray AS
+$BODY$
+        DECLARE
+                -- The variable used to track iteration over "from_array".
+                loop_offset integer;
+
+                -- The array to be returned by this function.
+                return_array from_array%TYPE;
+        BEGIN
+                -- Iterate over each element in "from_array".
+                FOR loop_offset IN ARRAY_LOWER(from_array, 1)..ARRAY_UPPER(from_array, 1) LOOP
+                        IF from_array[loop_offset] IS NOT NULL THEN -- If NULL, will omit from "return_array".
+                                return_array = ARRAY_APPEND(return_array, from_array[loop_offset]);
+                        END IF;
+                END LOOP;
+
+                RETURN return_array;
+        END;
+$BODY$ LANGUAGE plpgsql;
+DROP FUNCTION IF EXISTS migration_tools.anyarray_remove(anyarray, anyarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_remove(from_array anyarray, remove_array anyarray)
+        RETURNS anyarray AS
+$BODY$
+        DECLARE
+                -- The variable used to track iteration over "from_array".
+                loop_offset integer;
+
+
+                -- The array to be returned by this function.
+                return_array from_array%TYPE := '{}';
+        BEGIN
+                -- If either argument is NULL, there is nothing to do.
+                IF from_array IS NULL OR remove_array IS NULL THEN
+                        RETURN from_array;
+                END IF;
+
+                -- Iterate over each element in "from_array".
+                FOR loop_offset IN ARRAY_LOWER(from_array, 1)..ARRAY_UPPER(from_array, 1) LOOP
+                        -- If the element being iterated over is in "remove_array",
+                        -- do not append it to "return_array".
+                        IF (from_array[loop_offset] = ANY(remove_array)) IS DISTINCT FROM TRUE THEN
+                                return_array = ARRAY_APPEND(return_array, from_array[loop_offset]);
+                        END IF;
+                END LOOP;
+
+
+                RETURN return_array;
+        END;
+$BODY$ LANGUAGE plpgsql;
+
+
+DROP FUNCTION IF EXISTS migration_tools.anyarray_remove(anyarray, anynonarray);
+CREATE OR REPLACE FUNCTION migration_tools.anyarray_remove(from_array anyarray, remove_element anynonarray)
+        RETURNS anyarray AS
+$BODY$
+        BEGIN
+                RETURN ANYARRAY_REMOVE(from_array, ARRAY[remove_element]);
+        END;
+$BODY$ LANGUAGE plpgsql;