|
1 | 1 | --
|
2 | 2 | -- OPR_SANITY
|
3 | 3 | -- 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, |
5 | 5 | -- pg_amop, pg_amproc, pg_opclass, pg_opfamily, pg_index.
|
6 | 6 | --
|
7 | 7 | -- Every test failure in this file should be closely inspected.
|
@@ -319,6 +319,44 @@ ORDER BY 2;
|
319 | 319 | 3836 | range_recv
|
320 | 320 | (12 rows)
|
321 | 321 |
|
| 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 | + |
322 | 360 | -- Check for length inconsistencies between the various argument-info arrays.
|
323 | 361 | SELECT p1.oid, p1.proname
|
324 | 362 | FROM pg_proc as p1
|
@@ -781,6 +819,50 @@ WHERE c.castmethod = 'b' AND
|
781 | 819 | xml | character | 0 | a
|
782 | 820 | (7 rows)
|
783 | 821 |
|
| 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 | + |
784 | 866 | -- **************** pg_operator ****************
|
785 | 867 | -- Look for illegal values in pg_operator fields.
|
786 | 868 | SELECT p1.oid, p1.oprname
|
|
0 commit comments