Greetings,

I'm trying to track down some undocumented (or perhaps not well documented)
behavior I'm encountering in regards to custom functions (in plpgsql)
utilizing anyelement and anyarray as arguments and/or return types.

I arrived at this point when I was attempting to write the function
"ANYARRAY_REMOVE(anyarray, anyelement)", which returned anyarray.
This function would succeed when calling: SELECT
ANYARRAY_REMOVE(ARRAY[1,2,3], 2)
... But would fail when calling: SELECT ANYARRAY_REMOVE(ARRAY[1,2,3],
ARRAY[1,2])
... With the error: function anyarray_remove(integer[], integer[]) does not
exist.

>From that point I wrote a bunch of simply anyarray/element related
functions to better understand how these pseudo-types behave, which has
left me more confused than when I started.

Here are those functions, queries to interface with those functions, and
what I would expect each query to return or throw vs. what actually happens.

Nothing from what I have read and understand at these URLs document this
behavior:
-
http://forums.devshed.com/postgresql-help-21/what-s-anyarray-isn-t-it-the-same-as-array-148195.html
- http://www.postgresql.org/message-id/44649bb2.50...@tada.se
- http://www.postgresql.org/docs/9.1/static/extend-type-system.html

Queries Tested On:
- Windows 2003 R2 (64-Bit), PostgreSQL 9.1.0
- Ubuntu Linux 12.04 LTS (64-bit), PostgreSQL 9.2.4

/*============================================================================*/


DROP FUNCTION IF EXISTS anyel_anyel(anyelement);
CREATE OR REPLACE FUNCTION anyel_anyel(anyelement) RETURNS anyelement AS
$BODY$
    BEGIN
        RETURN $1;
    END;
$BODY$ LANGUAGE plpgsql;

/*----------------------------------------------------------------------------*/

-- Works as expected. Should accept TEXT, should output TEXT to match input
data-type.
--   Expected: Returns "hiho" as TEXT
--   Actual:   Returns "hiho" as TEXT
SELECT anyel_anyel('hiho'::TEXT);

-- Works as expected. Should accept INTEGER, should output INTEGER to match
input data-type.
---  Expected: Returns "1" as INTEGER
---  Actual:   Returns "1" as INTEGER
SELECT anyel_anyel(1::INTEGER);

-- Works as expected. Should accept TEXT[], should output TEXT[] to match
input data-type.
--   Expected: Returns "{one,two}" as TEXT[]
--   Actual:   Returns "{one,two}" as TEXT[]
SELECT anyel_anyel(ARRAY['one', 'two']::TEXT[]);

-- Works as expected. Should accept INTEGER[], should output INTEGER[] to
match input data-type.
--   Expected: Returns "{1,2,3}" as INTEGER[]
--   Actual:   Returns "{1,2,3}" as INTEGER[]
SELECT anyel_anyel(ARRAY[1,2,3]::INTEGER[]);


/*============================================================================*/


DROP FUNCTION IF EXISTS anyar_anyar(anyarray);
CREATE OR REPLACE FUNCTION anyar_anyar(anyarray) RETURNS anyarray AS $BODY$
    BEGIN
        RETURN $1;
    END;
$BODY$ LANGUAGE plpgsql;

/*----------------------------------------------------------------------------*/

-- Works as expected. Should not accept TEXT because not an array.
--   Expected: ERROR: function anyar_anyar(text) does not exist
--   Actual:   ERROR: function anyar_anyar(text) does not exist
SELECT anyar_anyar('hiho'::TEXT);

-- Works as expected. Should not accept INTEGER because not an array.
--   Expected: Throws ERROR: function anyar_anyar(integer) does not exist
--   Actual:   Throws ERROR: function anyar_anyar(integer) does not exist
SELECT anyar_anyar(1::INTEGER);

-- Works as expected. Should accept TEXT[], should output TEXT[].
--   Expected: Returns "{one,two}" as TEXT[]
--   Actual:   Returns "{one,two}" as TEXT[]
SELECT anyar_anyar(ARRAY['one', 'two']::TEXT[]);

-- Works as expected. Should accept INTEGER[], should output INTEGER[].
--   Expected: Returns "{1,2,3}" as INTEGER[]
--   Actual:   Returns "{1,2,3}" as INTEGER[]
SELECT anyar_anyar(ARRAY[1,2,3]::INTEGER[]);


/*============================================================================*/


DROP FUNCTION IF EXISTS anyar_anyel(anyarray);
CREATE OR REPLACE FUNCTION anyar_anyel(anyarray) RETURNS anyelement AS
$BODY$
    BEGIN
        RETURN $1;
    END;
$BODY$ LANGUAGE plpgsql;

/*----------------------------------------------------------------------------*/

-- Works as expected. Should not accept TEXT because not an array.
--   Expected: ERROR: function anyar_anyel(text) does not exist
--   Actual:   ERROR: function anyar_anyel(text) does not exist
SELECT anyar_anyel('hiho'::TEXT);

-- Works as expected: Should not accept INTEGER because not an array.
--   Expected: ERROR: function anyar_anyel(integer) does not exist
--   Actual:   function anyar_anyel(integer) does not exist
SELECT anyar_anyel(1::INTEGER);

-- Does not work as expected. Should accept TEXT[], should output TEXT[] to
match input data-type.
--   Expected: Returns "{one,two}" as TEXT[]
--   Actual:   Returns "{one,two}" as TEXT
SELECT anyar_anyel(ARRAY['one', 'two']::TEXT[]);

-- Does not work as expected. Should accept INTEGER[], should output
INTEGER[] to match input data-type.
--   Expected: Returns "{1,2,3}" as INTEGER[]
--   Actual:   ERROR: invalid input syntax for integer: "{1,2,3}"
--             CONTEXT: PL/pgSQL function "anyar_anyel" while casting
return value to function's return type
SELECT anyar_anyel(ARRAY[1,2,3]::INTEGER[]);


/*============================================================================*/


DROP FUNCTION IF EXISTS anyel_anyar(anyelement);
CREATE OR REPLACE FUNCTION anyel_anyar(anyelement) RETURNS anyarray AS
$BODY$
    BEGIN
        RETURN $1;
    END;
$BODY$ LANGUAGE plpgsql;

/*----------------------------------------------------------------------------*/

-- Works as expected: Should accept TEXT, should output TEXT to match input
data-type, but should fail because output musdt be array.
--   Expected: ERROR: array value must start with "{" or dimension
information
--   Actual:   ERROR: array value must start with "{" or dimension
information
--             CONTEXT: PL/pgSQL function "anyel_anyar" while casting
return value to function's return type
SELECT anyel_anyar('hiho'::TEXT);

-- Works as expected: Should accept INTEGER, should output INTEGER to match
input data-type, but should fail because output must be array.
--   Expected: ERROR: array value must start with "{" or dimension
information
--   Actual:   ERROR: array value must start with "{" or dimension
information
--             CONTEXT: PL/pgSQL function "anyel_anyar" while casting
return value to function's return type
SELECT anyel_anyar(1::INTEGER);

-- Does not work as expected. Should accept TEXT[], should output TEXT[].
--   Expected: Returns "{one,two}" as TEXT[]
--   Actual:   ERROR: could not find array type for data type text[]
SELECT anyel_anyar(ARRAY['one', 'two']::TEXT[]);

-- Does not work as expected. Should accept INTEGER[], should output TEXT[].
--   Expected: Returns "{1,2,3}" as INTEGER[]
--   Actual:   ERROR: could not find array type for data type integer[]
SELECT anyel_anyar(ARRAY[1,2,3]::INTEGER[]);

Reply via email to