Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 6303a57

Browse files
committed
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
1 parent 6d177e2 commit 6303a57

15 files changed

+216
-295
lines changed

src/test/regress/expected/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/constraints.out
22
/copy.out
3+
/create_function_0.out
34
/create_function_1.out
45
/create_function_2.out
56
/largeobject.out

src/test/regress/expected/conversion.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ DROP USER regress_conversion_user;
4141
-- Test built-in conversion functions.
4242
--
4343
-- Helper function to test a conversion. Uses the test_enc_conversion function
44-
-- that was created in the create_function_1 test.
44+
-- that was created in the create_function_0 test.
4545
create or replace function test_conv(
4646
input IN bytea,
4747
src_encoding IN text,

src/test/regress/expected/opr_sanity.out

-55
Original file line numberDiff line numberDiff line change
@@ -16,61 +16,6 @@
1616
--
1717
-- NB: run this test earlier than the create_operator test, because
1818
-- that test creates some bogus operators...
19-
-- Helper functions to deal with cases where binary-coercible matches are
20-
-- allowed.
21-
-- This should match IsBinaryCoercible() in parse_coerce.c.
22-
-- It doesn't currently know about some cases, notably domains, anyelement,
23-
-- anynonarray, anyenum, or record, but it doesn't need to (yet).
24-
create function binary_coercible(oid, oid) returns bool as $$
25-
begin
26-
if $1 = $2 then return true; end if;
27-
if EXISTS(select 1 from pg_catalog.pg_cast where
28-
castsource = $1 and casttarget = $2 and
29-
castmethod = 'b' and castcontext = 'i')
30-
then return true; end if;
31-
if $2 = 'pg_catalog.any'::pg_catalog.regtype then return true; end if;
32-
if $2 = 'pg_catalog.anyarray'::pg_catalog.regtype then
33-
if EXISTS(select 1 from pg_catalog.pg_type where
34-
oid = $1 and typelem != 0 and
35-
typsubscript = 'pg_catalog.array_subscript_handler'::pg_catalog.regproc)
36-
then return true; end if;
37-
end if;
38-
if $2 = 'pg_catalog.anyrange'::pg_catalog.regtype then
39-
if (select typtype from pg_catalog.pg_type where oid = $1) = 'r'
40-
then return true; end if;
41-
end if;
42-
if $2 = 'pg_catalog.anymultirange'::pg_catalog.regtype then
43-
if (select typtype from pg_catalog.pg_type where oid = $1) = 'm'
44-
then return true; end if;
45-
end if;
46-
return false;
47-
end
48-
$$ language plpgsql strict stable;
49-
-- This one ignores castcontext, so it will allow cases where an explicit
50-
-- (but still binary) cast would be required to convert the input type.
51-
-- We don't currently use this for any tests in this file, but it is a
52-
-- reasonable alternative definition for some scenarios.
53-
create function explicitly_binary_coercible(oid, oid) returns bool as $$
54-
begin
55-
if $1 = $2 then return true; end if;
56-
if EXISTS(select 1 from pg_catalog.pg_cast where
57-
castsource = $1 and casttarget = $2 and
58-
castmethod = 'b')
59-
then return true; end if;
60-
if $2 = 'pg_catalog.any'::pg_catalog.regtype then return true; end if;
61-
if $2 = 'pg_catalog.anyarray'::pg_catalog.regtype then
62-
if EXISTS(select 1 from pg_catalog.pg_type where
63-
oid = $1 and typelem != 0 and
64-
typsubscript = 'pg_catalog.array_subscript_handler'::pg_catalog.regproc)
65-
then return true; end if;
66-
end if;
67-
if $2 = 'pg_catalog.anyrange'::pg_catalog.regtype then
68-
if (select typtype from pg_catalog.pg_type where oid = $1) = 'r'
69-
then return true; end if;
70-
end if;
71-
return false;
72-
end
73-
$$ language plpgsql strict stable;
7419
-- **************** pg_proc ****************
7520
-- Look for illegal values in pg_proc fields.
7621
SELECT p1.oid, p1.proname

src/test/regress/expected/type_sanity.out

+1-1
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ WHERE (rngcollation = 0) != (typcollation = 0);
635635
(0 rows)
636636

637637
-- opclass had better be a btree opclass accepting the subtype.
638-
-- We must allow anyarray matches, cf opr_sanity's binary_coercible()
638+
-- We must allow anyarray matches, cf IsBinaryCoercible()
639639
SELECT p1.rngtypid, p1.rngsubtype, o.opcmethod, o.opcname
640640
FROM pg_range p1 JOIN pg_opclass o ON o.oid = p1.rngsubopc
641641
WHERE o.opcmethod != 403 OR
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
--
2+
-- CREATE_FUNCTION_0
3+
--
4+
5+
-- Create a bunch of C functions that will be used by later tests:
6+
7+
CREATE FUNCTION check_primary_key ()
8+
RETURNS trigger
9+
AS '@libdir@/refint@DLSUFFIX@'
10+
LANGUAGE C;
11+
12+
CREATE FUNCTION check_foreign_key ()
13+
RETURNS trigger
14+
AS '@libdir@/refint@DLSUFFIX@'
15+
LANGUAGE C;
16+
17+
CREATE FUNCTION autoinc ()
18+
RETURNS trigger
19+
AS '@libdir@/autoinc@DLSUFFIX@'
20+
LANGUAGE C;
21+
22+
CREATE FUNCTION trigger_return_old ()
23+
RETURNS trigger
24+
AS '@libdir@/regress@DLSUFFIX@'
25+
LANGUAGE C;
26+
27+
CREATE FUNCTION ttdummy ()
28+
RETURNS trigger
29+
AS '@libdir@/regress@DLSUFFIX@'
30+
LANGUAGE C;
31+
32+
CREATE FUNCTION set_ttdummy (int4)
33+
RETURNS int4
34+
AS '@libdir@/regress@DLSUFFIX@'
35+
LANGUAGE C STRICT;
36+
37+
CREATE FUNCTION make_tuple_indirect (record)
38+
RETURNS record
39+
AS '@libdir@/regress@DLSUFFIX@'
40+
LANGUAGE C STRICT;
41+
42+
CREATE FUNCTION test_atomic_ops()
43+
RETURNS bool
44+
AS '@libdir@/regress@DLSUFFIX@'
45+
LANGUAGE C;
46+
47+
CREATE FUNCTION test_fdw_handler()
48+
RETURNS fdw_handler
49+
AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler'
50+
LANGUAGE C;
51+
52+
CREATE FUNCTION test_support_func(internal)
53+
RETURNS internal
54+
AS '@libdir@/regress@DLSUFFIX@', 'test_support_func'
55+
LANGUAGE C STRICT;
56+
57+
CREATE FUNCTION test_opclass_options_func(internal)
58+
RETURNS void
59+
AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func'
60+
LANGUAGE C;
61+
62+
CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea)
63+
AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion'
64+
LANGUAGE C STRICT;
65+
66+
CREATE FUNCTION binary_coercible(oid, oid)
67+
RETURNS bool
68+
AS '@libdir@/regress@DLSUFFIX@', 'binary_coercible'
69+
LANGUAGE C STRICT STABLE PARALLEL SAFE;
70+
71+
-- Things that shouldn't work:
72+
73+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
74+
AS 'SELECT ''not an integer'';';
75+
76+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
77+
AS 'not even SQL';
78+
79+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
80+
AS 'SELECT 1, 2, 3;';
81+
82+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
83+
AS 'SELECT $2;';
84+
85+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
86+
AS 'a', 'b';
87+
88+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
89+
AS 'nosuchfile';
90+
91+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
92+
AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol';
93+
94+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
95+
AS 'nosuch';

src/test/regress/input/create_function_1.source

+2-86
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
-- CREATE_FUNCTION_1
33
--
44

5+
-- Create C functions needed by create_type.sql
6+
57
CREATE FUNCTION widget_in(cstring)
68
RETURNS widget
79
AS '@libdir@/regress@DLSUFFIX@'
@@ -21,89 +23,3 @@ CREATE FUNCTION int44out(city_budget)
2123
RETURNS cstring
2224
AS '@libdir@/regress@DLSUFFIX@'
2325
LANGUAGE C STRICT IMMUTABLE;
24-
25-
CREATE FUNCTION check_primary_key ()
26-
RETURNS trigger
27-
AS '@libdir@/refint@DLSUFFIX@'
28-
LANGUAGE C;
29-
30-
CREATE FUNCTION check_foreign_key ()
31-
RETURNS trigger
32-
AS '@libdir@/refint@DLSUFFIX@'
33-
LANGUAGE C;
34-
35-
CREATE FUNCTION autoinc ()
36-
RETURNS trigger
37-
AS '@libdir@/autoinc@DLSUFFIX@'
38-
LANGUAGE C;
39-
40-
CREATE FUNCTION trigger_return_old ()
41-
RETURNS trigger
42-
AS '@libdir@/regress@DLSUFFIX@'
43-
LANGUAGE C;
44-
45-
CREATE FUNCTION ttdummy ()
46-
RETURNS trigger
47-
AS '@libdir@/regress@DLSUFFIX@'
48-
LANGUAGE C;
49-
50-
CREATE FUNCTION set_ttdummy (int4)
51-
RETURNS int4
52-
AS '@libdir@/regress@DLSUFFIX@'
53-
LANGUAGE C STRICT;
54-
55-
CREATE FUNCTION make_tuple_indirect (record)
56-
RETURNS record
57-
AS '@libdir@/regress@DLSUFFIX@'
58-
LANGUAGE C STRICT;
59-
60-
CREATE FUNCTION test_atomic_ops()
61-
RETURNS bool
62-
AS '@libdir@/regress@DLSUFFIX@'
63-
LANGUAGE C;
64-
65-
-- Tests creating a FDW handler
66-
CREATE FUNCTION test_fdw_handler()
67-
RETURNS fdw_handler
68-
AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler'
69-
LANGUAGE C;
70-
71-
CREATE FUNCTION test_support_func(internal)
72-
RETURNS internal
73-
AS '@libdir@/regress@DLSUFFIX@', 'test_support_func'
74-
LANGUAGE C STRICT;
75-
76-
CREATE FUNCTION test_opclass_options_func(internal)
77-
RETURNS void
78-
AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func'
79-
LANGUAGE C;
80-
81-
CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea)
82-
AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion'
83-
LANGUAGE C STRICT;
84-
85-
-- Things that shouldn't work:
86-
87-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
88-
AS 'SELECT ''not an integer'';';
89-
90-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
91-
AS 'not even SQL';
92-
93-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
94-
AS 'SELECT 1, 2, 3;';
95-
96-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
97-
AS 'SELECT $2;';
98-
99-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
100-
AS 'a', 'b';
101-
102-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
103-
AS 'nosuchfile';
104-
105-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
106-
AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol';
107-
108-
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
109-
AS 'nosuch';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
--
2+
-- CREATE_FUNCTION_0
3+
--
4+
-- Create a bunch of C functions that will be used by later tests:
5+
CREATE FUNCTION check_primary_key ()
6+
RETURNS trigger
7+
AS '@libdir@/refint@DLSUFFIX@'
8+
LANGUAGE C;
9+
CREATE FUNCTION check_foreign_key ()
10+
RETURNS trigger
11+
AS '@libdir@/refint@DLSUFFIX@'
12+
LANGUAGE C;
13+
CREATE FUNCTION autoinc ()
14+
RETURNS trigger
15+
AS '@libdir@/autoinc@DLSUFFIX@'
16+
LANGUAGE C;
17+
CREATE FUNCTION trigger_return_old ()
18+
RETURNS trigger
19+
AS '@libdir@/regress@DLSUFFIX@'
20+
LANGUAGE C;
21+
CREATE FUNCTION ttdummy ()
22+
RETURNS trigger
23+
AS '@libdir@/regress@DLSUFFIX@'
24+
LANGUAGE C;
25+
CREATE FUNCTION set_ttdummy (int4)
26+
RETURNS int4
27+
AS '@libdir@/regress@DLSUFFIX@'
28+
LANGUAGE C STRICT;
29+
CREATE FUNCTION make_tuple_indirect (record)
30+
RETURNS record
31+
AS '@libdir@/regress@DLSUFFIX@'
32+
LANGUAGE C STRICT;
33+
CREATE FUNCTION test_atomic_ops()
34+
RETURNS bool
35+
AS '@libdir@/regress@DLSUFFIX@'
36+
LANGUAGE C;
37+
CREATE FUNCTION test_fdw_handler()
38+
RETURNS fdw_handler
39+
AS '@libdir@/regress@DLSUFFIX@', 'test_fdw_handler'
40+
LANGUAGE C;
41+
CREATE FUNCTION test_support_func(internal)
42+
RETURNS internal
43+
AS '@libdir@/regress@DLSUFFIX@', 'test_support_func'
44+
LANGUAGE C STRICT;
45+
CREATE FUNCTION test_opclass_options_func(internal)
46+
RETURNS void
47+
AS '@libdir@/regress@DLSUFFIX@', 'test_opclass_options_func'
48+
LANGUAGE C;
49+
CREATE FUNCTION test_enc_conversion(bytea, name, name, bool, validlen OUT int, result OUT bytea)
50+
AS '@libdir@/regress@DLSUFFIX@', 'test_enc_conversion'
51+
LANGUAGE C STRICT;
52+
CREATE FUNCTION binary_coercible(oid, oid)
53+
RETURNS bool
54+
AS '@libdir@/regress@DLSUFFIX@', 'binary_coercible'
55+
LANGUAGE C STRICT STABLE PARALLEL SAFE;
56+
-- Things that shouldn't work:
57+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
58+
AS 'SELECT ''not an integer'';';
59+
ERROR: return type mismatch in function declared to return integer
60+
DETAIL: Actual return type is text.
61+
CONTEXT: SQL function "test1"
62+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
63+
AS 'not even SQL';
64+
ERROR: syntax error at or near "not"
65+
LINE 2: AS 'not even SQL';
66+
^
67+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
68+
AS 'SELECT 1, 2, 3;';
69+
ERROR: return type mismatch in function declared to return integer
70+
DETAIL: Final statement must return exactly one column.
71+
CONTEXT: SQL function "test1"
72+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
73+
AS 'SELECT $2;';
74+
ERROR: there is no parameter $2
75+
LINE 2: AS 'SELECT $2;';
76+
^
77+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE SQL
78+
AS 'a', 'b';
79+
ERROR: only one AS item needed for language "sql"
80+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
81+
AS 'nosuchfile';
82+
ERROR: could not access file "nosuchfile": No such file or directory
83+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE C
84+
AS '@libdir@/regress@DLSUFFIX@', 'nosuchsymbol';
85+
ERROR: could not find function "nosuchsymbol" in file "@libdir@/regress@DLSUFFIX@"
86+
CREATE FUNCTION test1 (int) RETURNS int LANGUAGE internal
87+
AS 'nosuch';
88+
ERROR: there is no built-in function named "nosuch"

0 commit comments

Comments
 (0)