diff options
-rw-r--r-- | src/pl/plpython/expected/plpython_types.out | 28 | ||||
-rw-r--r-- | src/pl/plpython/expected/plpython_types_3.out | 28 | ||||
-rw-r--r-- | src/pl/plpython/plpy_typeio.c | 17 | ||||
-rw-r--r-- | src/pl/plpython/sql/plpython_types.sql | 20 |
4 files changed, 89 insertions, 4 deletions
diff --git a/src/pl/plpython/expected/plpython_types.out b/src/pl/plpython/expected/plpython_types.out index 91106e04550..785ffca9cd8 100644 --- a/src/pl/plpython/expected/plpython_types.out +++ b/src/pl/plpython/expected/plpython_types.out @@ -664,6 +664,34 @@ SELECT * FROM test_type_conversion_array_error(); ERROR: return value of function with array return type is not a Python sequence CONTEXT: while creating return value PL/Python function "test_type_conversion_array_error" +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]); +CREATE FUNCTION test_type_conversion_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$ +plpy.info(x, type(x)) +return x +$$ LANGUAGE plpythonu; +SELECT * FROM test_type_conversion_array_domain(ARRAY[0, 100]::ordered_pair_domain); +INFO: ([0, 100], <type 'list'>) +CONTEXT: PL/Python function "test_type_conversion_array_domain" + test_type_conversion_array_domain +----------------------------------- + {0,100} +(1 row) + +SELECT * FROM test_type_conversion_array_domain(NULL::ordered_pair_domain); +INFO: (None, <type 'NoneType'>) +CONTEXT: PL/Python function "test_type_conversion_array_domain" + test_type_conversion_array_domain +----------------------------------- + +(1 row) + +CREATE FUNCTION test_type_conversion_array_domain_check_violation() RETURNS ordered_pair_domain AS $$ +return [2,1] +$$ LANGUAGE plpythonu; +SELECT * FROM test_type_conversion_array_domain_check_violation(); +ERROR: value for domain ordered_pair_domain violates check constraint "ordered_pair_domain_check" +CONTEXT: while creating return value +PL/Python function "test_type_conversion_array_domain_check_violation" --- --- Composite types --- diff --git a/src/pl/plpython/expected/plpython_types_3.out b/src/pl/plpython/expected/plpython_types_3.out index 523c2ecda23..25331f268a1 100644 --- a/src/pl/plpython/expected/plpython_types_3.out +++ b/src/pl/plpython/expected/plpython_types_3.out @@ -664,6 +664,34 @@ SELECT * FROM test_type_conversion_array_error(); ERROR: return value of function with array return type is not a Python sequence CONTEXT: while creating return value PL/Python function "test_type_conversion_array_error" +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]); +CREATE FUNCTION test_type_conversion_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$ +plpy.info(x, type(x)) +return x +$$ LANGUAGE plpython3u; +SELECT * FROM test_type_conversion_array_domain(ARRAY[0, 100]::ordered_pair_domain); +INFO: ([0, 100], <class 'list'>) +CONTEXT: PL/Python function "test_type_conversion_array_domain" + test_type_conversion_array_domain +----------------------------------- + {0,100} +(1 row) + +SELECT * FROM test_type_conversion_array_domain(NULL::ordered_pair_domain); +INFO: (None, <class 'NoneType'>) +CONTEXT: PL/Python function "test_type_conversion_array_domain" + test_type_conversion_array_domain +----------------------------------- + +(1 row) + +CREATE FUNCTION test_type_conversion_array_domain_check_violation() RETURNS ordered_pair_domain AS $$ +return [2,1] +$$ LANGUAGE plpython3u; +SELECT * FROM test_type_conversion_array_domain_check_violation(); +ERROR: value for domain ordered_pair_domain violates check constraint "ordered_pair_domain_check" +CONTEXT: while creating return value +PL/Python function "test_type_conversion_array_domain_check_violation" --- --- Composite types --- diff --git a/src/pl/plpython/plpy_typeio.c b/src/pl/plpython/plpy_typeio.c index caccbf9b88f..0a2307abdb9 100644 --- a/src/pl/plpython/plpy_typeio.c +++ b/src/pl/plpython/plpy_typeio.c @@ -373,7 +373,7 @@ PLy_output_datum_func2(PLyObToDatum *arg, HeapTuple typeTup) arg->typioparam = getTypeIOParam(typeTup); arg->typbyval = typeStruct->typbyval; - element_type = get_element_type(arg->typoid); + element_type = get_base_element_type(arg->typoid); /* * Select a conversion function to convert Python objects to PostgreSQL @@ -427,7 +427,8 @@ static void PLy_input_datum_func2(PLyDatumToOb *arg, Oid typeOid, HeapTuple typeTup) { Form_pg_type typeStruct = (Form_pg_type) GETSTRUCT(typeTup); - Oid element_type = get_element_type(typeOid); + /* It's safe to handle domains of array types as its base array type. */ + Oid element_type = get_base_element_type(typeOid); /* Get the type's conversion information */ perm_fmgr_info(typeStruct->typoutput, &arg->typfunc); @@ -808,6 +809,7 @@ static Datum PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv) { ArrayType *array; + Datum rv; int i; Datum *elems; bool *nulls; @@ -844,8 +846,15 @@ PLySequence_ToArray(PLyObToDatum *arg, int32 typmod, PyObject *plrv) lbs = 1; array = construct_md_array(elems, nulls, 1, &len, &lbs, - get_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign); - return PointerGetDatum(array); + get_base_element_type(arg->typoid), arg->elm->typlen, arg->elm->typbyval, arg->elm->typalign); + /* + * If the result type is a domain of array, the resulting array must be + * checked. + */ + rv = PointerGetDatum(array); + if (get_typtype(arg->typoid) == TYPTYPE_DOMAIN) + domain_check(rv, false, arg->typoid, &arg->typfunc.fn_extra, arg->typfunc.fn_mcxt); + return rv; } diff --git a/src/pl/plpython/sql/plpython_types.sql b/src/pl/plpython/sql/plpython_types.sql index e63d07e1f9a..ee6b0e9e981 100644 --- a/src/pl/plpython/sql/plpython_types.sql +++ b/src/pl/plpython/sql/plpython_types.sql @@ -294,6 +294,26 @@ $$ LANGUAGE plpythonu; SELECT * FROM test_type_conversion_array_error(); +-- +-- Domains over arrays +-- + +CREATE DOMAIN ordered_pair_domain AS integer[] CHECK (array_length(VALUE,1)=2 AND VALUE[1] < VALUE[2]); + +CREATE FUNCTION test_type_conversion_array_domain(x ordered_pair_domain) RETURNS ordered_pair_domain AS $$ +plpy.info(x, type(x)) +return x +$$ LANGUAGE plpythonu; + +SELECT * FROM test_type_conversion_array_domain(ARRAY[0, 100]::ordered_pair_domain); +SELECT * FROM test_type_conversion_array_domain(NULL::ordered_pair_domain); + +CREATE FUNCTION test_type_conversion_array_domain_check_violation() RETURNS ordered_pair_domain AS $$ +return [2,1] +$$ LANGUAGE plpythonu; +SELECT * FROM test_type_conversion_array_domain_check_violation(); + + --- --- Composite types --- |