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

Lines changed: 83 additions & 1 deletion
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

Lines changed: 72 additions & 1 deletion
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy