mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
In opr_sanity regression test, check for unexpected uses of cstring.
In light of commit ea0d494dae0d3d6f, it seems like a good idea to add a regression test that will complain about random functions taking or returning cstring. Only I/O support functions and encoding conversion functions should be declared that way. While at it, add some checks that encoding conversion functions are declared properly. Since pg_conversion isn't populated manually, it's not quite as necessary to check its contents as it is for catalogs like pg_proc; but one thing we definitely have not tested in the past is whether the identified conproc for a conversion actually does that conversion vs. some other one.
This commit is contained in:
parent
ea0d494dae
commit
921191912c
@ -1,7 +1,7 @@
|
|||||||
--
|
--
|
||||||
-- OPR_SANITY
|
-- OPR_SANITY
|
||||||
-- Sanity checks for common errors in making operator/procedure system tables:
|
-- Sanity checks for common errors in making operator/procedure system tables:
|
||||||
-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
|
-- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am,
|
||||||
-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
|
-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
|
||||||
--
|
--
|
||||||
-- Every test failure in this file should be closely inspected.
|
-- Every test failure in this file should be closely inspected.
|
||||||
@ -319,6 +319,44 @@ ORDER BY 2;
|
|||||||
3836 | range_recv
|
3836 | range_recv
|
||||||
(12 rows)
|
(12 rows)
|
||||||
|
|
||||||
|
-- Look for functions that accept cstring and are neither datatype input
|
||||||
|
-- functions nor encoding conversion functions. It's almost never a good
|
||||||
|
-- idea to use cstring input for a function meant to be called from SQL;
|
||||||
|
-- text should be used instead, because cstring lacks suitable casts.
|
||||||
|
-- As of 9.6 this query should find only cstring_out and cstring_send.
|
||||||
|
-- However, we must manually exclude shell_in, which might or might not be
|
||||||
|
-- rejected by the EXISTS clause depending on whether there are currently
|
||||||
|
-- any shell types.
|
||||||
|
SELECT p1.oid, p1.proname
|
||||||
|
FROM pg_proc as p1
|
||||||
|
WHERE 'cstring'::regtype = ANY (p1.proargtypes)
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid)
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid)
|
||||||
|
AND p1.oid != 'shell_in(cstring)'::regprocedure
|
||||||
|
ORDER BY 1;
|
||||||
|
oid | proname
|
||||||
|
------+--------------
|
||||||
|
2293 | cstring_out
|
||||||
|
2501 | cstring_send
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
-- Likewise, look for functions that return cstring and aren't datatype output
|
||||||
|
-- functions nor typmod output functions.
|
||||||
|
-- As of 9.6 this query should find only cstring_in and cstring_recv.
|
||||||
|
-- However, we must manually exclude shell_out.
|
||||||
|
SELECT p1.oid, p1.proname
|
||||||
|
FROM pg_proc as p1
|
||||||
|
WHERE p1.prorettype = 'cstring'::regtype
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid)
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid)
|
||||||
|
AND p1.oid != 'shell_out(opaque)'::regprocedure
|
||||||
|
ORDER BY 1;
|
||||||
|
oid | proname
|
||||||
|
------+--------------
|
||||||
|
2292 | cstring_in
|
||||||
|
2500 | cstring_recv
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
-- Check for length inconsistencies between the various argument-info arrays.
|
-- Check for length inconsistencies between the various argument-info arrays.
|
||||||
SELECT p1.oid, p1.proname
|
SELECT p1.oid, p1.proname
|
||||||
FROM pg_proc as p1
|
FROM pg_proc as p1
|
||||||
@ -781,6 +819,50 @@ WHERE c.castmethod = 'b' AND
|
|||||||
xml | character | 0 | a
|
xml | character | 0 | a
|
||||||
(7 rows)
|
(7 rows)
|
||||||
|
|
||||||
|
-- **************** pg_conversion ****************
|
||||||
|
-- Look for illegal values in pg_conversion fields.
|
||||||
|
SELECT p1.oid, p1.conname
|
||||||
|
FROM pg_conversion as p1
|
||||||
|
WHERE p1.conproc = 0 OR
|
||||||
|
pg_encoding_to_char(conforencoding) = '' OR
|
||||||
|
pg_encoding_to_char(contoencoding) = '';
|
||||||
|
oid | conname
|
||||||
|
-----+---------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- Look for conprocs that don't have the expected signature.
|
||||||
|
SELECT p.oid, p.proname, c.oid, c.conname
|
||||||
|
FROM pg_proc p, pg_conversion c
|
||||||
|
WHERE p.oid = c.conproc AND
|
||||||
|
(p.prorettype != 'void'::regtype OR p.proretset OR
|
||||||
|
p.pronargs != 5 OR
|
||||||
|
p.proargtypes[0] != 'int4'::regtype OR
|
||||||
|
p.proargtypes[1] != 'int4'::regtype OR
|
||||||
|
p.proargtypes[2] != 'cstring'::regtype OR
|
||||||
|
p.proargtypes[3] != 'internal'::regtype OR
|
||||||
|
p.proargtypes[4] != 'int4'::regtype);
|
||||||
|
oid | proname | oid | conname
|
||||||
|
-----+---------+-----+---------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
-- Check for conprocs that don't perform the specific conversion that
|
||||||
|
-- pg_conversion alleges they do, by trying to invoke each conversion
|
||||||
|
-- on some simple ASCII data. (The conproc should throw an error if
|
||||||
|
-- it doesn't accept the encodings that are passed to it.)
|
||||||
|
-- Unfortunately, we can't test non-default conprocs this way, because
|
||||||
|
-- there is no way to ask convert() to invoke them, and we cannot call
|
||||||
|
-- them directly from SQL. But there are no non-default built-in
|
||||||
|
-- conversions anyway.
|
||||||
|
-- (Similarly, this doesn't cope with any search path issues.)
|
||||||
|
SELECT p1.oid, p1.conname
|
||||||
|
FROM pg_conversion as p1
|
||||||
|
WHERE condefault AND
|
||||||
|
convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
|
||||||
|
pg_encoding_to_char(contoencoding)) != 'ABC';
|
||||||
|
oid | conname
|
||||||
|
-----+---------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
-- **************** pg_operator ****************
|
-- **************** pg_operator ****************
|
||||||
-- Look for illegal values in pg_operator fields.
|
-- Look for illegal values in pg_operator fields.
|
||||||
SELECT p1.oid, p1.oprname
|
SELECT p1.oid, p1.oprname
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
--
|
--
|
||||||
-- OPR_SANITY
|
-- OPR_SANITY
|
||||||
-- Sanity checks for common errors in making operator/procedure system tables:
|
-- Sanity checks for common errors in making operator/procedure system tables:
|
||||||
-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
|
-- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am,
|
||||||
-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
|
-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
|
||||||
--
|
--
|
||||||
-- Every test failure in this file should be closely inspected.
|
-- Every test failure in this file should be closely inspected.
|
||||||
@ -250,6 +250,36 @@ WHERE p1.prorettype IN
|
|||||||
'anyrange'::regtype = ANY (p1.proargtypes))
|
'anyrange'::regtype = ANY (p1.proargtypes))
|
||||||
ORDER BY 2;
|
ORDER BY 2;
|
||||||
|
|
||||||
|
-- Look for functions that accept cstring and are neither datatype input
|
||||||
|
-- functions nor encoding conversion functions. It's almost never a good
|
||||||
|
-- idea to use cstring input for a function meant to be called from SQL;
|
||||||
|
-- text should be used instead, because cstring lacks suitable casts.
|
||||||
|
-- As of 9.6 this query should find only cstring_out and cstring_send.
|
||||||
|
-- However, we must manually exclude shell_in, which might or might not be
|
||||||
|
-- rejected by the EXISTS clause depending on whether there are currently
|
||||||
|
-- any shell types.
|
||||||
|
|
||||||
|
SELECT p1.oid, p1.proname
|
||||||
|
FROM pg_proc as p1
|
||||||
|
WHERE 'cstring'::regtype = ANY (p1.proargtypes)
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid)
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid)
|
||||||
|
AND p1.oid != 'shell_in(cstring)'::regprocedure
|
||||||
|
ORDER BY 1;
|
||||||
|
|
||||||
|
-- Likewise, look for functions that return cstring and aren't datatype output
|
||||||
|
-- functions nor typmod output functions.
|
||||||
|
-- As of 9.6 this query should find only cstring_in and cstring_recv.
|
||||||
|
-- However, we must manually exclude shell_out.
|
||||||
|
|
||||||
|
SELECT p1.oid, p1.proname
|
||||||
|
FROM pg_proc as p1
|
||||||
|
WHERE p1.prorettype = 'cstring'::regtype
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid)
|
||||||
|
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid)
|
||||||
|
AND p1.oid != 'shell_out(opaque)'::regprocedure
|
||||||
|
ORDER BY 1;
|
||||||
|
|
||||||
-- Check for length inconsistencies between the various argument-info arrays.
|
-- Check for length inconsistencies between the various argument-info arrays.
|
||||||
|
|
||||||
SELECT p1.oid, p1.proname
|
SELECT p1.oid, p1.proname
|
||||||
@ -426,6 +456,47 @@ WHERE c.castmethod = 'b' AND
|
|||||||
k.castsource = c.casttarget AND
|
k.castsource = c.casttarget AND
|
||||||
k.casttarget = c.castsource);
|
k.casttarget = c.castsource);
|
||||||
|
|
||||||
|
|
||||||
|
-- **************** pg_conversion ****************
|
||||||
|
|
||||||
|
-- Look for illegal values in pg_conversion fields.
|
||||||
|
|
||||||
|
SELECT p1.oid, p1.conname
|
||||||
|
FROM pg_conversion as p1
|
||||||
|
WHERE p1.conproc = 0 OR
|
||||||
|
pg_encoding_to_char(conforencoding) = '' OR
|
||||||
|
pg_encoding_to_char(contoencoding) = '';
|
||||||
|
|
||||||
|
-- Look for conprocs that don't have the expected signature.
|
||||||
|
|
||||||
|
SELECT p.oid, p.proname, c.oid, c.conname
|
||||||
|
FROM pg_proc p, pg_conversion c
|
||||||
|
WHERE p.oid = c.conproc AND
|
||||||
|
(p.prorettype != 'void'::regtype OR p.proretset OR
|
||||||
|
p.pronargs != 5 OR
|
||||||
|
p.proargtypes[0] != 'int4'::regtype OR
|
||||||
|
p.proargtypes[1] != 'int4'::regtype OR
|
||||||
|
p.proargtypes[2] != 'cstring'::regtype OR
|
||||||
|
p.proargtypes[3] != 'internal'::regtype OR
|
||||||
|
p.proargtypes[4] != 'int4'::regtype);
|
||||||
|
|
||||||
|
-- Check for conprocs that don't perform the specific conversion that
|
||||||
|
-- pg_conversion alleges they do, by trying to invoke each conversion
|
||||||
|
-- on some simple ASCII data. (The conproc should throw an error if
|
||||||
|
-- it doesn't accept the encodings that are passed to it.)
|
||||||
|
-- Unfortunately, we can't test non-default conprocs this way, because
|
||||||
|
-- there is no way to ask convert() to invoke them, and we cannot call
|
||||||
|
-- them directly from SQL. But there are no non-default built-in
|
||||||
|
-- conversions anyway.
|
||||||
|
-- (Similarly, this doesn't cope with any search path issues.)
|
||||||
|
|
||||||
|
SELECT p1.oid, p1.conname
|
||||||
|
FROM pg_conversion as p1
|
||||||
|
WHERE condefault AND
|
||||||
|
convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
|
||||||
|
pg_encoding_to_char(contoencoding)) != 'ABC';
|
||||||
|
|
||||||
|
|
||||||
-- **************** pg_operator ****************
|
-- **************** pg_operator ****************
|
||||||
|
|
||||||
-- Look for illegal values in pg_operator fields.
|
-- Look for illegal values in pg_operator fields.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user