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

Commit 9211919

Browse files
committed
In opr_sanity regression test, check for unexpected uses of cstring.
In light of commit ea0d494, 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.
1 parent ea0d494 commit 9211919

File tree

2 files changed

+155
-2
lines changed

2 files changed

+155
-2
lines changed

src/test/regress/expected/opr_sanity.out

+83-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--
22
-- OPR_SANITY
33
-- Sanity checks for common errors in making operator/procedure system tables:
4-
-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
4+
-- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am,
55
-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
66
--
77
-- Every test failure in this file should be closely inspected.
@@ -319,6 +319,44 @@ ORDER BY 2;
319319
3836 | range_recv
320320
(12 rows)
321321

322+
-- Look for functions that accept cstring and are neither datatype input
323+
-- functions nor encoding conversion functions. It's almost never a good
324+
-- idea to use cstring input for a function meant to be called from SQL;
325+
-- text should be used instead, because cstring lacks suitable casts.
326+
-- As of 9.6 this query should find only cstring_out and cstring_send.
327+
-- However, we must manually exclude shell_in, which might or might not be
328+
-- rejected by the EXISTS clause depending on whether there are currently
329+
-- any shell types.
330+
SELECT p1.oid, p1.proname
331+
FROM pg_proc as p1
332+
WHERE 'cstring'::regtype = ANY (p1.proargtypes)
333+
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid)
334+
AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid)
335+
AND p1.oid != 'shell_in(cstring)'::regprocedure
336+
ORDER BY 1;
337+
oid | proname
338+
------+--------------
339+
2293 | cstring_out
340+
2501 | cstring_send
341+
(2 rows)
342+
343+
-- Likewise, look for functions that return cstring and aren't datatype output
344+
-- functions nor typmod output functions.
345+
-- As of 9.6 this query should find only cstring_in and cstring_recv.
346+
-- However, we must manually exclude shell_out.
347+
SELECT p1.oid, p1.proname
348+
FROM pg_proc as p1
349+
WHERE p1.prorettype = 'cstring'::regtype
350+
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid)
351+
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid)
352+
AND p1.oid != 'shell_out(opaque)'::regprocedure
353+
ORDER BY 1;
354+
oid | proname
355+
------+--------------
356+
2292 | cstring_in
357+
2500 | cstring_recv
358+
(2 rows)
359+
322360
-- Check for length inconsistencies between the various argument-info arrays.
323361
SELECT p1.oid, p1.proname
324362
FROM pg_proc as p1
@@ -781,6 +819,50 @@ WHERE c.castmethod = 'b' AND
781819
xml | character | 0 | a
782820
(7 rows)
783821

822+
-- **************** pg_conversion ****************
823+
-- Look for illegal values in pg_conversion fields.
824+
SELECT p1.oid, p1.conname
825+
FROM pg_conversion as p1
826+
WHERE p1.conproc = 0 OR
827+
pg_encoding_to_char(conforencoding) = '' OR
828+
pg_encoding_to_char(contoencoding) = '';
829+
oid | conname
830+
-----+---------
831+
(0 rows)
832+
833+
-- Look for conprocs that don't have the expected signature.
834+
SELECT p.oid, p.proname, c.oid, c.conname
835+
FROM pg_proc p, pg_conversion c
836+
WHERE p.oid = c.conproc AND
837+
(p.prorettype != 'void'::regtype OR p.proretset OR
838+
p.pronargs != 5 OR
839+
p.proargtypes[0] != 'int4'::regtype OR
840+
p.proargtypes[1] != 'int4'::regtype OR
841+
p.proargtypes[2] != 'cstring'::regtype OR
842+
p.proargtypes[3] != 'internal'::regtype OR
843+
p.proargtypes[4] != 'int4'::regtype);
844+
oid | proname | oid | conname
845+
-----+---------+-----+---------
846+
(0 rows)
847+
848+
-- Check for conprocs that don't perform the specific conversion that
849+
-- pg_conversion alleges they do, by trying to invoke each conversion
850+
-- on some simple ASCII data. (The conproc should throw an error if
851+
-- it doesn't accept the encodings that are passed to it.)
852+
-- Unfortunately, we can't test non-default conprocs this way, because
853+
-- there is no way to ask convert() to invoke them, and we cannot call
854+
-- them directly from SQL. But there are no non-default built-in
855+
-- conversions anyway.
856+
-- (Similarly, this doesn't cope with any search path issues.)
857+
SELECT p1.oid, p1.conname
858+
FROM pg_conversion as p1
859+
WHERE condefault AND
860+
convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
861+
pg_encoding_to_char(contoencoding)) != 'ABC';
862+
oid | conname
863+
-----+---------
864+
(0 rows)
865+
784866
-- **************** pg_operator ****************
785867
-- Look for illegal values in pg_operator fields.
786868
SELECT p1.oid, p1.oprname

src/test/regress/sql/opr_sanity.sql

+72-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--
22
-- OPR_SANITY
33
-- Sanity checks for common errors in making operator/procedure system tables:
4-
-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am,
4+
-- pg_operator, pg_proc, pg_cast, pg_conversion, pg_aggregate, pg_am,
55
-- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
66
--
77
-- Every test failure in this file should be closely inspected.
@@ -250,6 +250,36 @@ WHERE p1.prorettype IN
250250
'anyrange'::regtype = ANY (p1.proargtypes))
251251
ORDER BY 2;
252252

253+
-- Look for functions that accept cstring and are neither datatype input
254+
-- functions nor encoding conversion functions. It's almost never a good
255+
-- idea to use cstring input for a function meant to be called from SQL;
256+
-- text should be used instead, because cstring lacks suitable casts.
257+
-- As of 9.6 this query should find only cstring_out and cstring_send.
258+
-- However, we must manually exclude shell_in, which might or might not be
259+
-- rejected by the EXISTS clause depending on whether there are currently
260+
-- any shell types.
261+
262+
SELECT p1.oid, p1.proname
263+
FROM pg_proc as p1
264+
WHERE 'cstring'::regtype = ANY (p1.proargtypes)
265+
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typinput = p1.oid)
266+
AND NOT EXISTS(SELECT 1 FROM pg_conversion WHERE conproc = p1.oid)
267+
AND p1.oid != 'shell_in(cstring)'::regprocedure
268+
ORDER BY 1;
269+
270+
-- Likewise, look for functions that return cstring and aren't datatype output
271+
-- functions nor typmod output functions.
272+
-- As of 9.6 this query should find only cstring_in and cstring_recv.
273+
-- However, we must manually exclude shell_out.
274+
275+
SELECT p1.oid, p1.proname
276+
FROM pg_proc as p1
277+
WHERE p1.prorettype = 'cstring'::regtype
278+
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typoutput = p1.oid)
279+
AND NOT EXISTS(SELECT 1 FROM pg_type WHERE typmodout = p1.oid)
280+
AND p1.oid != 'shell_out(opaque)'::regprocedure
281+
ORDER BY 1;
282+
253283
-- Check for length inconsistencies between the various argument-info arrays.
254284

255285
SELECT p1.oid, p1.proname
@@ -426,6 +456,47 @@ WHERE c.castmethod = 'b' AND
426456
k.castsource = c.casttarget AND
427457
k.casttarget = c.castsource);
428458

459+
460+
-- **************** pg_conversion ****************
461+
462+
-- Look for illegal values in pg_conversion fields.
463+
464+
SELECT p1.oid, p1.conname
465+
FROM pg_conversion as p1
466+
WHERE p1.conproc = 0 OR
467+
pg_encoding_to_char(conforencoding) = '' OR
468+
pg_encoding_to_char(contoencoding) = '';
469+
470+
-- Look for conprocs that don't have the expected signature.
471+
472+
SELECT p.oid, p.proname, c.oid, c.conname
473+
FROM pg_proc p, pg_conversion c
474+
WHERE p.oid = c.conproc AND
475+
(p.prorettype != 'void'::regtype OR p.proretset OR
476+
p.pronargs != 5 OR
477+
p.proargtypes[0] != 'int4'::regtype OR
478+
p.proargtypes[1] != 'int4'::regtype OR
479+
p.proargtypes[2] != 'cstring'::regtype OR
480+
p.proargtypes[3] != 'internal'::regtype OR
481+
p.proargtypes[4] != 'int4'::regtype);
482+
483+
-- Check for conprocs that don't perform the specific conversion that
484+
-- pg_conversion alleges they do, by trying to invoke each conversion
485+
-- on some simple ASCII data. (The conproc should throw an error if
486+
-- it doesn't accept the encodings that are passed to it.)
487+
-- Unfortunately, we can't test non-default conprocs this way, because
488+
-- there is no way to ask convert() to invoke them, and we cannot call
489+
-- them directly from SQL. But there are no non-default built-in
490+
-- conversions anyway.
491+
-- (Similarly, this doesn't cope with any search path issues.)
492+
493+
SELECT p1.oid, p1.conname
494+
FROM pg_conversion as p1
495+
WHERE condefault AND
496+
convert('ABC'::bytea, pg_encoding_to_char(conforencoding),
497+
pg_encoding_to_char(contoencoding)) != 'ABC';
498+
499+
429500
-- **************** pg_operator ****************
430501

431502
-- Look for illegal values in pg_operator fields.

0 commit comments

Comments
 (0)