From 6303a5730914dfe6ef2709b28b225553315c573c Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 11 May 2021 14:28:11 -0400 Subject: [PATCH] Replace opr_sanity test's binary_coercible() function with C code. opr_sanity's binary_coercible() function has always been meant to match the parser's notion of binary coercibility, but it also has always been a rather poor approximation of the parser's real rules (as embodied in IsBinaryCoercible()). That hasn't bit us so far, but it's predictable that it will eventually. It also now emerges that implementing this check in plpgsql performs absolutely horribly in clobber-cache-always testing. (Perhaps we could do something about that, but I suspect it just means that plpgsql is exploiting catalog caching to the hilt.) Hence, let's replace binary_coercible() with a C shim that directly invokes IsBinaryCoercible(), eliminating both the semantic hazard and the performance issue. Most of regress.c's C functions are declared in create_function_1, but we can't simply move that to before opr_sanity/type_sanity since those tests would complain about the resulting shell types. I chose to split it into create_function_0 and create_function_1. Since create_function_0 now runs as part of a parallel group while create_function_1 doesn't, reduce the latter to create just those functions that opr_sanity and type_sanity would whine about. To make room for create_function_0 in the second parallel group of tests, move tstypes to the third parallel group. In passing, clean up some ordering deviations between parallel_schedule and serial_schedule. Discussion: https://postgr.es/m/292305.1620503097@sss.pgh.pa.us --- src/test/regress/expected/.gitignore | 1 + src/test/regress/expected/conversion.out | 2 +- src/test/regress/expected/opr_sanity.out | 55 ----------- src/test/regress/expected/type_sanity.out | 2 +- .../regress/input/create_function_0.source | 95 +++++++++++++++++++ .../regress/input/create_function_1.source | 88 +---------------- .../regress/output/create_function_0.source | 88 +++++++++++++++++ .../regress/output/create_function_1.source | 82 +--------------- src/test/regress/parallel_schedule | 7 +- src/test/regress/regress.c | 12 +++ src/test/regress/serial_schedule | 15 +-- src/test/regress/sql/.gitignore | 1 + src/test/regress/sql/conversion.sql | 2 +- src/test/regress/sql/opr_sanity.sql | 59 ------------ src/test/regress/sql/type_sanity.sql | 2 +- 15 files changed, 216 insertions(+), 295 deletions(-) create mode 100644 src/test/regress/input/create_function_0.source create mode 100644 src/test/regress/output/create_function_0.source diff --git a/src/test/regress/expected/.gitignore b/src/test/regress/expected/.gitignore index 93c56c85a0..b99caf5f40 100644 --- a/src/test/regress/expected/.gitignore +++ b/src/test/regress/expected/.gitignore @@ -1,5 +1,6 @@ /constraints.out /copy.out +/create_function_0.out /create_function_1.out /create_function_2.out /largeobject.out diff --git a/src/test/regress/expected/conversion.out b/src/test/regress/expected/conversion.out index e34ab20974..04fdcba496 100644 --- a/src/test/regress/expected/conversion.out +++ b/src/test/regress/expected/conversion.out @@ -41,7 +41,7 @@ DROP USER regress_conversion_user; -- Test built-in conversion functions. -- -- Helper function to test a conversion. Uses the test_enc_conversion function --- that was created in the create_function_1 test. +-- that was created in the create_function_0 test. create or replace function test_conv( input IN bytea, src_encoding IN text, diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 7a0d345b60..562b586d8e 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -16,61 +16,6 @@ -- -- NB: run this test earlier than the create_operator test, because -- that test creates some bogus operators... --- Helper functions to deal with cases where binary-coercible matches are --- allowed. --- This should match IsBinaryCoercible() in parse_coerce.c. --- It doesn't currently know about some cases, notably domains, anyelement, --- anynonarray, anyenum, or record, but it doesn't need to (yet). -create function binary_coercible(oid, oid) returns bool as $$ -begin - if $1 = $2 then return true; end if; - if EXISTS(select 1 from pg_catalog.pg_cast where - castsource = $1 and casttarget = $2 and - castmethod = 'b' and castcontext = 'i') - then return true; end if; - if $2 = 'pg_catalog.any'::pg_catalog.regtype then return true; end if; - if $2 = 'pg_catalog.anyarray'::pg_catalog.regtype then - if EXISTS(select 1 from pg_catalog.pg_type where - oid = $1 and typelem != 0 and - typsubscript = 'pg_catalog.array_subscript_handler'::pg_catalog.regproc) - then return true; end if; - end if; - if $2 = 'pg_catalog.anyrange'::pg_catalog.regtype then - if (select typtype from pg_catalog.pg_type where oid = $1) = 'r' - then return true; end if; - end if; - if $2 = 'pg_catalog.anymultirange'::pg_catalog.regtype then - if (select typtype from pg_catalog.pg_type where oid = $1) = 'm' - then return true; end if; - end if; - return false; -end -$$ language plpgsql strict stable; --- This one ignores castcontext, so it will allow cases where an explicit --- (but still binary) cast would be required to convert the input type. --- We don't currently use this for any tests in this file, but it is a --- reasonable alternative definition for some scenarios. -create function explicitly_binary_coercible(oid, oid) returns bool as $$ -begin - if $1 = $2 then return true; end if; - if EXISTS(select 1 from pg_catalog.pg_cast where - castsource = $1 and casttarget = $2 and - castmethod = 'b') - then return true; end if; - if $2 = 'pg_catalog.any'::pg_catalog.regtype then return true; end if; - if $2 = 'pg_catalog.anyarray'::pg_catalog.regtype then - if EXISTS(select 1 from pg_catalog.pg_type where - oid = $1 and typelem != 0 and - typsubscript = 'pg_catalog.array_subscript_handler'::pg_catalog.regproc) - then return true; end if; - end if; - if $2 = 'pg_catalog.anyrange'::pg_catalog.regtype then - if (select typtype from pg_catalog.pg_type where oid = $1) = 'r' - then return true; end if; - end if; - return false; -end -$$ language plpgsql strict stable; -- **************** pg_proc **************** -- Look for illegal values in pg_proc fields. SELECT p1.oid, p1.proname diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out index 5480f979c6..f567fd378e 100644 --- a/src/test/regress/expected/type_sanity.out +++ b/src/test/regress/expected/type_sanity.out @@ -635,7 +635,7 @@ WHERE (rngcollation = 0) != (typcollation = 0); (0 rows) -- opclass had better be a btree opclass accepting the subtype. --- We must allow anyarray matches, cf opr_sanity's binary_coercible() +-- We must allow anyarray matches, cf IsBinaryCoercible() SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc WHERE o.opcmethod != 403 OR diff --git a/src/test/regress/input/create_function_0.source b/src/test/regress/input/create_function_0.source new file mode 100644 index 0000000000..f47f635789 --- /dev/null +++ b/src/test/regress/input/create_function_0.source @@ -0,0 +1,95 @@ +-- +-- CREATE_FUNCTION_0 +-- + +-- Create a bunch of C functions that will be used by later tests: + +CREATE FUNCTION check_primary_key () + RETURNS trigger + AS '@libdir@/refint@DLSUFFIX@' + LANGUAGE C; + +CREATE FUNCTION check_foreign_key () + RETURNS trigger + AS '@libdir@/refint@DLSUFFIX@' + LANGUAGE C; + +CREATE FUNCTION autoinc () + RETURNS trigger + AS '@libdir@/autoinc@DLSUFFIX@' + LANGUAGE C; + +CREATE FUNCTION trigger_return_old () + RETURNS trigger + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C; + +CREATE FUNCTION ttdummy () + RETURNS trigger + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C; + +CREATE FUNCTION set_ttdummy (int4) + RETURNS int4 + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C STRICT; + +CREATE FUNCTION make_tuple_indirect (record) + RETURNS record + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C STRICT; + +CREATE FUNCTION test_atomic_ops() + RETURNS bool + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C; + +CREATE FUNCTION test_fdw_handler() + RETURNS fdw_handler + AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler' + LANGUAGE C; + +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS '@libdir@/regress@DLSUFFIX@', 'test_support_func' + LANGUAGE C STRICT; + +CREATE FUNCTION test_opclass_options_func(internal) + RETURNS void + AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func' + LANGUAGE C; + +CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) + AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion' + LANGUAGE C STRICT; + +CREATE FUNCTION binary_coercible(oid, oid) + RETURNS bool + AS '@libdir@/regress@DLSUFFIX@', 'binary_coercible' + LANGUAGE C STRICT STABLE PARALLEL SAFE; + +-- Things that shouldn't work: + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT ''not an integer'';'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'not even SQL'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT 1, 2, 3;'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT $2;'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'a', 'b'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS 'nosuchfile'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol'; + +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal + AS 'nosuch'; diff --git a/src/test/regress/input/create_function_1.source b/src/test/regress/input/create_function_1.source index 6c69b7fe6c..79a41562bb 100644 --- a/src/test/regress/input/create_function_1.source +++ b/src/test/regress/input/create_function_1.source @@ -2,6 +2,8 @@ -- CREATE_FUNCTION_1 -- +-- Create C functions needed by create_type.sql + CREATE FUNCTION widget_in(cstring) RETURNS widget AS '@libdir@/regress@DLSUFFIX@' @@ -21,89 +23,3 @@ CREATE FUNCTION int44out(city_budget) RETURNS cstring AS '@libdir@/regress@DLSUFFIX@' LANGUAGE C STRICT IMMUTABLE; - -CREATE FUNCTION check_primary_key () - RETURNS trigger - AS '@libdir@/refint@DLSUFFIX@' - LANGUAGE C; - -CREATE FUNCTION check_foreign_key () - RETURNS trigger - AS '@libdir@/refint@DLSUFFIX@' - LANGUAGE C; - -CREATE FUNCTION autoinc () - RETURNS trigger - AS '@libdir@/autoinc@DLSUFFIX@' - LANGUAGE C; - -CREATE FUNCTION trigger_return_old () - RETURNS trigger - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C; - -CREATE FUNCTION ttdummy () - RETURNS trigger - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C; - -CREATE FUNCTION set_ttdummy (int4) - RETURNS int4 - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C STRICT; - -CREATE FUNCTION make_tuple_indirect (record) - RETURNS record - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C STRICT; - -CREATE FUNCTION test_atomic_ops() - RETURNS bool - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C; - --- Tests creating a FDW handler -CREATE FUNCTION test_fdw_handler() - RETURNS fdw_handler - AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler' - LANGUAGE C; - -CREATE FUNCTION test_support_func(internal) - RETURNS internal - AS '@libdir@/regress@DLSUFFIX@', 'test_support_func' - LANGUAGE C STRICT; - -CREATE FUNCTION test_opclass_options_func(internal) - RETURNS void - AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func' - LANGUAGE C; - -CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) - AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion' - LANGUAGE C STRICT; - --- Things that shouldn't work: - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'SELECT ''not an integer'';'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'not even SQL'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'SELECT 1, 2, 3;'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'SELECT $2;'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'a', 'b'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C - AS 'nosuchfile'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C - AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol'; - -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal - AS 'nosuch'; diff --git a/src/test/regress/output/create_function_0.source b/src/test/regress/output/create_function_0.source new file mode 100644 index 0000000000..342bc40e11 --- /dev/null +++ b/src/test/regress/output/create_function_0.source @@ -0,0 +1,88 @@ +-- +-- CREATE_FUNCTION_0 +-- +-- Create a bunch of C functions that will be used by later tests: +CREATE FUNCTION check_primary_key () + RETURNS trigger + AS '@libdir@/refint@DLSUFFIX@' + LANGUAGE C; +CREATE FUNCTION check_foreign_key () + RETURNS trigger + AS '@libdir@/refint@DLSUFFIX@' + LANGUAGE C; +CREATE FUNCTION autoinc () + RETURNS trigger + AS '@libdir@/autoinc@DLSUFFIX@' + LANGUAGE C; +CREATE FUNCTION trigger_return_old () + RETURNS trigger + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C; +CREATE FUNCTION ttdummy () + RETURNS trigger + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C; +CREATE FUNCTION set_ttdummy (int4) + RETURNS int4 + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C STRICT; +CREATE FUNCTION make_tuple_indirect (record) + RETURNS record + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C STRICT; +CREATE FUNCTION test_atomic_ops() + RETURNS bool + AS '@libdir@/regress@DLSUFFIX@' + LANGUAGE C; +CREATE FUNCTION test_fdw_handler() + RETURNS fdw_handler + AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler' + LANGUAGE C; +CREATE FUNCTION test_support_func(internal) + RETURNS internal + AS '@libdir@/regress@DLSUFFIX@', 'test_support_func' + LANGUAGE C STRICT; +CREATE FUNCTION test_opclass_options_func(internal) + RETURNS void + AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func' + LANGUAGE C; +CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) + AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion' + LANGUAGE C STRICT; +CREATE FUNCTION binary_coercible(oid, oid) + RETURNS bool + AS '@libdir@/regress@DLSUFFIX@', 'binary_coercible' + LANGUAGE C STRICT STABLE PARALLEL SAFE; +-- Things that shouldn't work: +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT ''not an integer'';'; +ERROR: return type mismatch in function declared to return integer +DETAIL: Actual return type is text. +CONTEXT: SQL function "test1" +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'not even SQL'; +ERROR: syntax error at or near "not" +LINE 2: AS 'not even SQL'; + ^ +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT 1, 2, 3;'; +ERROR: return type mismatch in function declared to return integer +DETAIL: Final statement must return exactly one column. +CONTEXT: SQL function "test1" +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'SELECT $2;'; +ERROR: there is no parameter $2 +LINE 2: AS 'SELECT $2;'; + ^ +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL + AS 'a', 'b'; +ERROR: only one AS item needed for language "sql" +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS 'nosuchfile'; +ERROR: could not access file "nosuchfile": No such file or directory +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C + AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol'; +ERROR: could not find function "nosuchsymbol" in file "@libdir@/regress@DLSUFFIX@" +CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal + AS 'nosuch'; +ERROR: there is no built-in function named "nosuch" diff --git a/src/test/regress/output/create_function_1.source b/src/test/regress/output/create_function_1.source index c66146db9d..616b610e86 100644 --- a/src/test/regress/output/create_function_1.source +++ b/src/test/regress/output/create_function_1.source @@ -1,6 +1,7 @@ -- -- CREATE_FUNCTION_1 -- +-- Create C functions needed by create_type.sql CREATE FUNCTION widget_in(cstring) RETURNS widget AS '@libdir@/regress@DLSUFFIX@' @@ -23,84 +24,3 @@ CREATE FUNCTION int44out(city_budget) AS '@libdir@/regress@DLSUFFIX@' LANGUAGE C STRICT IMMUTABLE; NOTICE: argument type city_budget is only a shell -CREATE FUNCTION check_primary_key () - RETURNS trigger - AS '@libdir@/refint@DLSUFFIX@' - LANGUAGE C; -CREATE FUNCTION check_foreign_key () - RETURNS trigger - AS '@libdir@/refint@DLSUFFIX@' - LANGUAGE C; -CREATE FUNCTION autoinc () - RETURNS trigger - AS '@libdir@/autoinc@DLSUFFIX@' - LANGUAGE C; -CREATE FUNCTION trigger_return_old () - RETURNS trigger - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C; -CREATE FUNCTION ttdummy () - RETURNS trigger - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C; -CREATE FUNCTION set_ttdummy (int4) - RETURNS int4 - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C STRICT; -CREATE FUNCTION make_tuple_indirect (record) - RETURNS record - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C STRICT; -CREATE FUNCTION test_atomic_ops() - RETURNS bool - AS '@libdir@/regress@DLSUFFIX@' - LANGUAGE C; --- Tests creating a FDW handler -CREATE FUNCTION test_fdw_handler() - RETURNS fdw_handler - AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler' - LANGUAGE C; -CREATE FUNCTION test_support_func(internal) - RETURNS internal - AS '@libdir@/regress@DLSUFFIX@', 'test_support_func' - LANGUAGE C STRICT; -CREATE FUNCTION test_opclass_options_func(internal) - RETURNS void - AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func' - LANGUAGE C; -CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea) - AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion' - LANGUAGE C STRICT; --- Things that shouldn't work: -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'SELECT ''not an integer'';'; -ERROR: return type mismatch in function declared to return integer -DETAIL: Actual return type is text. -CONTEXT: SQL function "test1" -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'not even SQL'; -ERROR: syntax error at or near "not" -LINE 2: AS 'not even SQL'; - ^ -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'SELECT 1, 2, 3;'; -ERROR: return type mismatch in function declared to return integer -DETAIL: Final statement must return exactly one column. -CONTEXT: SQL function "test1" -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'SELECT $2;'; -ERROR: there is no parameter $2 -LINE 2: AS 'SELECT $2;'; - ^ -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL - AS 'a', 'b'; -ERROR: only one AS item needed for language "sql" -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C - AS 'nosuchfile'; -ERROR: could not access file "nosuchfile": No such file or directory -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C - AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol'; -ERROR: could not find function "nosuchsymbol" in file "@libdir@/regress@DLSUFFIX@" -CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal - AS 'nosuch'; -ERROR: there is no built-in function named "nosuch" diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index a091300857..22b0d3584d 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -20,16 +20,17 @@ test: boolean char name varchar text int2 int4 int8 oid float4 float8 bit numeri # strings depends on char, varchar and text # numerology depends on int2, int4, int8, float4, float8 # multirangetypes depends on rangetypes -# multirangetypes shouldn't be in the one group with type_sanity +# multirangetypes shouldn't run concurrently with type_sanity # ---------- -test: strings numerology point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 tstypes multirangetypes +test: strings numerology point lseg line box path polygon circle date time timetz timestamp timestamptz interval inet macaddr macaddr8 multirangetypes create_function_0 # ---------- # Another group of parallel tests # geometry depends on point, lseg, box, path, polygon and circle # horology depends on interval, timetz, timestamp, timestamptz +# opr_sanity depends on create_function_0 # ---------- -test: geometry horology regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc +test: geometry horology tstypes regex type_sanity opr_sanity misc_sanity comments expressions unicode xid mvcc # ---------- # These four each depend on the previous one diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index 1990cbb6a1..d8756e5ba0 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -36,6 +36,7 @@ #include "nodes/supportnodes.h" #include "optimizer/optimizer.h" #include "optimizer/plancat.h" +#include "parser/parse_coerce.h" #include "port/atomics.h" #include "storage/spin.h" #include "utils/builtins.h" @@ -1194,3 +1195,14 @@ test_enc_conversion(PG_FUNCTION_ARGS) PG_RETURN_DATUM(HeapTupleGetDatum(tuple)); } + +/* Provide SQL access to IsBinaryCoercible() */ +PG_FUNCTION_INFO_V1(binary_coercible); +Datum +binary_coercible(PG_FUNCTION_ARGS) +{ + Oid srctype = PG_GETARG_OID(0); + Oid targettype = PG_GETARG_OID(1); + + PG_RETURN_BOOL(IsBinaryCoercible(srctype, targettype)); +} diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 5644847601..6e9cdf92af 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -10,8 +10,6 @@ test: int2 test: int4 test: int8 test: oid -test: xid -test: mvcc test: float4 test: float8 test: bit @@ -21,7 +19,6 @@ test: uuid test: enum test: money test: rangetypes -test: multirangetypes test: pg_lsn test: regproc test: strings @@ -42,9 +39,11 @@ test: interval test: inet test: macaddr test: macaddr8 -test: tstypes +test: multirangetypes +test: create_function_0 test: geometry test: horology +test: tstypes test: regex test: type_sanity test: opr_sanity @@ -52,6 +51,8 @@ test: misc_sanity test: comments test: expressions test: unicode +test: xid +test: mvcc test: create_function_1 test: create_type test: create_table @@ -92,7 +93,6 @@ test: select_distinct_on test: select_implicit test: select_having test: subselect -test: incremental_sort test: union test: case test: join @@ -109,8 +109,6 @@ test: delete test: namespace test: prepared_xacts test: brin -test: brin_bloom -test: brin_multi test: gin test: gist test: spgist @@ -130,6 +128,8 @@ test: password test: identity test: generated test: join_hash +test: brin_bloom +test: brin_multi test: create_table_like test: alter_generic test: alter_operator @@ -143,6 +143,7 @@ test: tid test: tidscan test: tidrangescan test: collate.icu.utf8 +test: incremental_sort test: rules test: psql test: psql_crosstab diff --git a/src/test/regress/sql/.gitignore b/src/test/regress/sql/.gitignore index 46c8112094..fe14af6ae7 100644 --- a/src/test/regress/sql/.gitignore +++ b/src/test/regress/sql/.gitignore @@ -1,5 +1,6 @@ /constraints.sql /copy.sql +/create_function_0.sql /create_function_1.sql /create_function_2.sql /largeobject.sql diff --git a/src/test/regress/sql/conversion.sql b/src/test/regress/sql/conversion.sql index ea85f20ed8..8358682432 100644 --- a/src/test/regress/sql/conversion.sql +++ b/src/test/regress/sql/conversion.sql @@ -40,7 +40,7 @@ DROP USER regress_conversion_user; -- -- Helper function to test a conversion. Uses the test_enc_conversion function --- that was created in the create_function_1 test. +-- that was created in the create_function_0 test. create or replace function test_conv( input IN bytea, src_encoding IN text, diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql index 393acdf8c3..5a9c479692 100644 --- a/src/test/regress/sql/opr_sanity.sql +++ b/src/test/regress/sql/opr_sanity.sql @@ -18,65 +18,6 @@ -- that test creates some bogus operators... --- Helper functions to deal with cases where binary-coercible matches are --- allowed. - --- This should match IsBinaryCoercible() in parse_coerce.c. --- It doesn't currently know about some cases, notably domains, anyelement, --- anynonarray, anyenum, or record, but it doesn't need to (yet). -create function binary_coercible(oid, oid) returns bool as $$ -begin - if $1 = $2 then return true; end if; - if EXISTS(select 1 from pg_catalog.pg_cast where - castsource = $1 and casttarget = $2 and - castmethod = 'b' and castcontext = 'i') - then return true; end if; - if $2 = 'pg_catalog.any'::pg_catalog.regtype then return true; end if; - if $2 = 'pg_catalog.anyarray'::pg_catalog.regtype then - if EXISTS(select 1 from pg_catalog.pg_type where - oid = $1 and typelem != 0 and - typsubscript = 'pg_catalog.array_subscript_handler'::pg_catalog.regproc) - then return true; end if; - end if; - if $2 = 'pg_catalog.anyrange'::pg_catalog.regtype then - if (select typtype from pg_catalog.pg_type where oid = $1) = 'r' - then return true; end if; - end if; - if $2 = 'pg_catalog.anymultirange'::pg_catalog.regtype then - if (select typtype from pg_catalog.pg_type where oid = $1) = 'm' - then return true; end if; - end if; - return false; -end -$$ language plpgsql strict stable; - --- This one ignores castcontext, so it will allow cases where an explicit --- (but still binary) cast would be required to convert the input type. --- We don't currently use this for any tests in this file, but it is a --- reasonable alternative definition for some scenarios. -create function explicitly_binary_coercible(oid, oid) returns bool as $$ -begin - if $1 = $2 then return true; end if; - if EXISTS(select 1 from pg_catalog.pg_cast where - castsource = $1 and casttarget = $2 and - castmethod = 'b') - then return true; end if; - if $2 = 'pg_catalog.any'::pg_catalog.regtype then return true; end if; - if $2 = 'pg_catalog.anyarray'::pg_catalog.regtype then - if EXISTS(select 1 from pg_catalog.pg_type where - oid = $1 and typelem != 0 and - typsubscript = 'pg_catalog.array_subscript_handler'::pg_catalog.regproc) - then return true; end if; - end if; - if $2 = 'pg_catalog.anyrange'::pg_catalog.regtype then - if (select typtype from pg_catalog.pg_type where oid = $1) = 'r' - then return true; end if; - end if; - return false; -end -$$ language plpgsql strict stable; - - -- **************** pg_proc **************** -- Look for illegal values in pg_proc fields. diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql index 4739aca84a..404c3a2043 100644 --- a/src/test/regress/sql/type_sanity.sql +++ b/src/test/regress/sql/type_sanity.sql @@ -465,7 +465,7 @@ FROM pg_range p1 JOIN pg_type t ON t.oid = p1.rngsubtype WHERE (rngcollation = 0) != (typcollation = 0); -- opclass had better be a btree opclass accepting the subtype. --- We must allow anyarray matches, cf opr_sanity's binary_coercible() +-- We must allow anyarray matches, cf IsBinaryCoercible() SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc