summaryrefslogtreecommitdiff
path: root/src/test/regress
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/regress')
-rw-r--r--src/test/regress/expected/copy2.out4
-rw-r--r--src/test/regress/expected/create_type.out29
-rw-r--r--src/test/regress/expected/opr_sanity.out46
-rw-r--r--src/test/regress/expected/plpgsql.out44
-rw-r--r--src/test/regress/expected/type_sanity.out67
-rw-r--r--src/test/regress/input/create_function_1.source26
-rw-r--r--src/test/regress/output/create_function_1.source27
-rw-r--r--src/test/regress/regress.c62
-rw-r--r--src/test/regress/sql/copy2.sql4
-rw-r--r--src/test/regress/sql/create_type.sql26
-rw-r--r--src/test/regress/sql/drop.sql4
-rw-r--r--src/test/regress/sql/opr_sanity.sql46
-rw-r--r--src/test/regress/sql/plpgsql.sql44
-rw-r--r--src/test/regress/sql/type_sanity.sql54
14 files changed, 336 insertions, 147 deletions
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index 300e1744a24..fa421e40bad 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -6,13 +6,13 @@ CREATE TABLE x (
e text
);
NOTICE: CREATE TABLE will create implicit sequence 'x_a_seq' for SERIAL column 'x.a'
-CREATE FUNCTION fn_x_before () RETURNS OPAQUE AS '
+CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
BEGIN
NEW.e := ''before trigger fired''::text;
return NEW;
END;
' language 'plpgsql';
-CREATE FUNCTION fn_x_after () RETURNS OPAQUE AS '
+CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS '
BEGIN
UPDATE x set e=''after trigger fired'' where c=''stuff'';
return NULL;
diff --git a/src/test/regress/expected/create_type.out b/src/test/regress/expected/create_type.out
index 68dc8fbd5e5..a177153d298 100644
--- a/src/test/regress/expected/create_type.out
+++ b/src/test/regress/expected/create_type.out
@@ -14,18 +14,39 @@ CREATE TYPE city_budget (
element = int4
);
-- Test type-related default values (broken in releases before PG 7.2)
+-- Make dummy I/O routines using the existing internal support for int4, text
+CREATE FUNCTION int42_in(cstring)
+ RETURNS int42
+ AS 'int4in'
+ LANGUAGE 'internal' WITH (isStrict);
+WARNING: ProcedureCreate: type int42 is not yet defined
+CREATE FUNCTION int42_out(int42)
+ RETURNS cstring
+ AS 'int4out'
+ LANGUAGE 'internal' WITH (isStrict);
+WARNING: Argument type "int42" is only a shell
+CREATE FUNCTION text_w_default_in(cstring)
+ RETURNS text_w_default
+ AS 'textin'
+ LANGUAGE 'internal' WITH (isStrict);
+WARNING: ProcedureCreate: type text_w_default is not yet defined
+CREATE FUNCTION text_w_default_out(text_w_default)
+ RETURNS cstring
+ AS 'textout'
+ LANGUAGE 'internal' WITH (isStrict);
+WARNING: Argument type "text_w_default" is only a shell
CREATE TYPE int42 (
internallength = 4,
- input = int4in,
- output = int4out,
+ input = int42_in,
+ output = int42_out,
alignment = int4,
default = 42,
passedbyvalue
);
CREATE TYPE text_w_default (
internallength = variable,
- input = textin,
- output = textout,
+ input = text_w_default_in,
+ output = text_w_default_out,
alignment = int4,
default = 'zippo'
);
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index cb1193b0407..efdc8c6a500 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -16,16 +16,23 @@
-- that test creates some bogus operators...
-- **************** pg_proc ****************
-- Look for illegal values in pg_proc fields.
--- NOTE: currently there are a few pg_proc entries that have prorettype = 0.
--- Someday that ought to be cleaned up.
+-- NOTE: in reality pronargs could be more than 10, but I'm too lazy to put
+-- a larger number of proargtypes check clauses in here. If we ever have
+-- more-than-10-arg functions in the standard catalogs, extend this query.
SELECT p1.oid, p1.proname
FROM pg_proc as p1
-WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
- p1.pronargs < 0 OR p1.pronargs > 16)
- AND p1.proname !~ '^pl[^_]+_call_handler$'
- AND p1.proname !~ '^RI_FKey_'
- AND p1.proname !~ 'costestimate$'
- AND p1.proname != 'update_pg_pwd_and_pg_group';
+WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
+ p1.pronargs < 0 OR p1.pronargs > 10 OR
+ (p1.proargtypes[0] = 0 AND p1.pronargs > 0) OR
+ (p1.proargtypes[1] = 0 AND p1.pronargs > 1) OR
+ (p1.proargtypes[2] = 0 AND p1.pronargs > 2) OR
+ (p1.proargtypes[3] = 0 AND p1.pronargs > 3) OR
+ (p1.proargtypes[4] = 0 AND p1.pronargs > 4) OR
+ (p1.proargtypes[5] = 0 AND p1.pronargs > 5) OR
+ (p1.proargtypes[6] = 0 AND p1.pronargs > 6) OR
+ (p1.proargtypes[7] = 0 AND p1.pronargs > 7) OR
+ (p1.proargtypes[8] = 0 AND p1.pronargs > 8) OR
+ (p1.proargtypes[9] = 0 AND p1.pronargs > 9);
oid | proname
-----+---------
(0 rows)
@@ -217,7 +224,7 @@ WHERE c.castfunc = 0 AND NOT c.castimplicit;
SELECT *
FROM pg_cast c
WHERE c.castfunc = 0 AND
- NOT EXISTS (SELECT * FROM pg_cast k
+ NOT EXISTS (SELECT 1 FROM pg_cast k
WHERE k.castfunc = 0 AND
k.castsource = c.casttarget AND
k.casttarget = c.castsource);
@@ -341,7 +348,7 @@ WHERE p1.oprlsortop != 0 AND
SELECT p1.oid, p1.oprname FROM pg_operator AS p1
WHERE p1.oprlsortop != 0 AND NOT
- EXISTS(SELECT * FROM pg_operator AS p2 WHERE
+ EXISTS(SELECT 1 FROM pg_operator AS p2 WHERE
p2.oprname = '<' AND
p2.oprleft = p1.oprleft AND
p2.oprright = p1.oprright AND
@@ -352,7 +359,7 @@ WHERE p1.oprlsortop != 0 AND NOT
SELECT p1.oid, p1.oprname FROM pg_operator AS p1
WHERE p1.oprlsortop != 0 AND NOT
- EXISTS(SELECT * FROM pg_operator AS p2 WHERE
+ EXISTS(SELECT 1 FROM pg_operator AS p2 WHERE
p2.oprname = '>' AND
p2.oprleft = p1.oprleft AND
p2.oprright = p1.oprright AND
@@ -468,15 +475,17 @@ WHERE p1.oprcode = p2.oid AND
-- If oprrest is set, the operator must return boolean,
-- and it must link to a proc with the right signature
-- to be a restriction selectivity estimator.
--- The proc signature we want is: float8 proc(opaque, oid, opaque, int4)
+-- The proc signature we want is: float8 proc(internal, oid, internal, int4)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprrest = p2.oid AND
(p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR
- p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
- p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 'int4'::regtype);
+ p2.proargtypes[0] != 'internal'::regtype OR
+ p2.proargtypes[1] != 'oid'::regtype OR
+ p2.proargtypes[2] != 'internal'::regtype OR
+ p2.proargtypes[3] != 'int4'::regtype);
oid | oprname | oid | proname
-----+---------+-----+---------
(0 rows)
@@ -484,15 +493,16 @@ WHERE p1.oprrest = p2.oid AND
-- If oprjoin is set, the operator must be a binary boolean op,
-- and it must link to a proc with the right signature
-- to be a join selectivity estimator.
--- The proc signature we want is: float8 proc(opaque, oid, opaque)
+-- The proc signature we want is: float8 proc(internal, oid, internal)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
WHERE p1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 3 OR
- p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
- p2.proargtypes[2] != 0);
+ p2.proargtypes[0] != 'internal'::regtype OR
+ p2.proargtypes[1] != 'oid'::regtype OR
+ p2.proargtypes[2] != 'internal'::regtype);
oid | oprname | oid | proname
-----+---------+-----+---------
(0 rows)
@@ -547,7 +557,7 @@ WHERE a.aggfnoid = p.oid AND
a.aggtranstype != p2.prorettype OR
a.aggtranstype != p2.proargtypes[0] OR
NOT ((p2.pronargs = 2 AND p.proargtypes[0] = p2.proargtypes[1]) OR
- (p2.pronargs = 1 AND p.proargtypes[0] = 0)));
+ (p2.pronargs = 1 AND p.proargtypes[0] = '"any"'::regtype)));
aggfnoid | proname | oid | proname
----------+---------+-----+-------------
2121 | max | 768 | int4larger
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index 91d7c34b663..7682be33eb7 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -74,7 +74,7 @@ create unique index PHone_name on PHone using btree (slotname bpchar_ops);
-- * AFTER UPDATE on Room
-- * - If room no changes let wall slots follow
-- ************************************************************
-create function tg_room_au() returns opaque as '
+create function tg_room_au() returns trigger as '
begin
if new.roomno != old.roomno then
update WSlot set roomno = new.roomno where roomno = old.roomno;
@@ -88,7 +88,7 @@ create trigger tg_room_au after update
-- * AFTER DELETE on Room
-- * - delete wall slots in this room
-- ************************************************************
-create function tg_room_ad() returns opaque as '
+create function tg_room_ad() returns trigger as '
begin
delete from WSlot where roomno = old.roomno;
return old;
@@ -100,7 +100,7 @@ create trigger tg_room_ad after delete
-- * BEFORE INSERT or UPDATE on WSlot
-- * - Check that room exists
-- ************************************************************
-create function tg_wslot_biu() returns opaque as '
+create function tg_wslot_biu() returns trigger as '
begin
if count(*) = 0 from Room where roomno = new.roomno then
raise exception ''Room % does not exist'', new.roomno;
@@ -114,7 +114,7 @@ create trigger tg_wslot_biu before insert or update
-- * AFTER UPDATE on PField
-- * - Let PSlots of this field follow
-- ************************************************************
-create function tg_pfield_au() returns opaque as '
+create function tg_pfield_au() returns trigger as '
begin
if new.name != old.name then
update PSlot set pfname = new.name where pfname = old.name;
@@ -128,7 +128,7 @@ create trigger tg_pfield_au after update
-- * AFTER DELETE on PField
-- * - Remove all slots of this patchfield
-- ************************************************************
-create function tg_pfield_ad() returns opaque as '
+create function tg_pfield_ad() returns trigger as '
begin
delete from PSlot where pfname = old.name;
return old;
@@ -140,7 +140,7 @@ create trigger tg_pfield_ad after delete
-- * BEFORE INSERT or UPDATE on PSlot
-- * - Ensure that our patchfield does exist
-- ************************************************************
-create function tg_pslot_biu() returns opaque as '
+create function tg_pslot_biu() returns trigger as '
declare
pfrec record;
rename new to ps;
@@ -158,7 +158,7 @@ create trigger tg_pslot_biu before insert or update
-- * AFTER UPDATE on System
-- * - If system name changes let interfaces follow
-- ************************************************************
-create function tg_system_au() returns opaque as '
+create function tg_system_au() returns trigger as '
begin
if new.name != old.name then
update IFace set sysname = new.name where sysname = old.name;
@@ -172,7 +172,7 @@ create trigger tg_system_au after update
-- * BEFORE INSERT or UPDATE on IFace
-- * - set the slotname to IF.sysname.ifname
-- ************************************************************
-create function tg_iface_biu() returns opaque as '
+create function tg_iface_biu() returns trigger as '
declare
sname text;
sysrec record;
@@ -197,7 +197,7 @@ create trigger tg_iface_biu before insert or update
-- * AFTER INSERT or UPDATE or DELETE on Hub
-- * - insert/delete/rename slots as required
-- ************************************************************
-create function tg_hub_a() returns opaque as '
+create function tg_hub_a() returns trigger as '
declare
hname text;
dummy integer;
@@ -250,7 +250,7 @@ end;
-- * - prevent from manual manipulation
-- * - set the slotname to HS.hubname.slotno
-- ************************************************************
-create function tg_hslot_biu() returns opaque as '
+create function tg_hslot_biu() returns trigger as '
declare
sname text;
xname HSlot.slotname%TYPE;
@@ -286,7 +286,7 @@ create trigger tg_hslot_biu before insert or update
-- * BEFORE DELETE on HSlot
-- * - prevent from manual manipulation
-- ************************************************************
-create function tg_hslot_bd() returns opaque as '
+create function tg_hslot_bd() returns trigger as '
declare
hubrec record;
begin
@@ -306,7 +306,7 @@ create trigger tg_hslot_bd before delete
-- * BEFORE INSERT on all slots
-- * - Check name prefix
-- ************************************************************
-create function tg_chkslotname() returns opaque as '
+create function tg_chkslotname() returns trigger as '
begin
if substr(new.slotname, 1, 2) != tg_argv[0] then
raise exception ''slotname must begin with %'', tg_argv[0];
@@ -328,7 +328,7 @@ create trigger tg_chkslotname before insert
-- * BEFORE INSERT or UPDATE on all slots with slotlink
-- * - Set slotlink to empty string if NULL value given
-- ************************************************************
-create function tg_chkslotlink() returns opaque as '
+create function tg_chkslotlink() returns trigger as '
begin
if new.slotlink isnull then
new.slotlink := '''';
@@ -350,7 +350,7 @@ create trigger tg_chkslotlink before insert or update
-- * BEFORE INSERT or UPDATE on all slots with backlink
-- * - Set backlink to empty string if NULL value given
-- ************************************************************
-create function tg_chkbacklink() returns opaque as '
+create function tg_chkbacklink() returns trigger as '
begin
if new.backlink isnull then
new.backlink := '''';
@@ -368,7 +368,7 @@ create trigger tg_chkbacklink before insert or update
-- * BEFORE UPDATE on PSlot
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_pslot_bu() returns opaque as '
+create function tg_pslot_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from PSlot where slotname = old.slotname;
@@ -394,7 +394,7 @@ create trigger tg_pslot_bu before update
-- * BEFORE UPDATE on WSlot
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_wslot_bu() returns opaque as '
+create function tg_wslot_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from WSlot where slotname = old.slotname;
@@ -420,7 +420,7 @@ create trigger tg_wslot_bu before update
-- * BEFORE UPDATE on PLine
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_pline_bu() returns opaque as '
+create function tg_pline_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from PLine where slotname = old.slotname;
@@ -446,7 +446,7 @@ create trigger tg_pline_bu before update
-- * BEFORE UPDATE on IFace
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_iface_bu() returns opaque as '
+create function tg_iface_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from IFace where slotname = old.slotname;
@@ -472,7 +472,7 @@ create trigger tg_iface_bu before update
-- * BEFORE UPDATE on HSlot
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_hslot_bu() returns opaque as '
+create function tg_hslot_bu() returns trigger as '
begin
if new.slotname != old.slotname or new.hubname != old.hubname then
delete from HSlot where slotname = old.slotname;
@@ -498,7 +498,7 @@ create trigger tg_hslot_bu before update
-- * BEFORE UPDATE on PHone
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_phone_bu() returns opaque as '
+create function tg_phone_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from PHone where slotname = old.slotname;
@@ -522,7 +522,7 @@ create trigger tg_phone_bu before update
-- * AFTER INSERT or UPDATE or DELETE on slot with backlink
-- * - Ensure that the opponent correctly points back to us
-- ************************************************************
-create function tg_backlink_a() returns opaque as '
+create function tg_backlink_a() returns trigger as '
declare
dummy integer;
begin
@@ -666,7 +666,7 @@ end;
-- * AFTER INSERT or UPDATE or DELETE on slot with slotlink
-- * - Ensure that the opponent correctly points back to us
-- ************************************************************
-create function tg_slotlink_a() returns opaque as '
+create function tg_slotlink_a() returns trigger as '
declare
dummy integer;
begin
diff --git a/src/test/regress/expected/type_sanity.out b/src/test/regress/expected/type_sanity.out
index 68abfec74f3..e0890fb01af 100644
--- a/src/test/regress/expected/type_sanity.out
+++ b/src/test/regress/expected/type_sanity.out
@@ -15,13 +15,12 @@
-- Look for illegal values in pg_type fields.
SELECT p1.oid, p1.typname
FROM pg_type as p1
-WHERE (p1.typlen <= 0 AND p1.typlen != -1) OR
- p1.typtype not in('b', 'c', 'd', 'p') OR
+WHERE p1.typnamespace = 0 OR
+ (p1.typlen <= 0 AND p1.typlen != -1) OR
+ (p1.typtype not in ('b', 'c', 'd', 'p')) OR
NOT p1.typisdefined OR
- (p1.typalign != 'c' AND p1.typalign != 's' AND
- p1.typalign != 'i' AND p1.typalign != 'd') OR
- (p1.typstorage != 'p' AND p1.typstorage != 'x' AND
- p1.typstorage != 'e' AND p1.typstorage != 'm');
+ (p1.typalign not in ('c', 's', 'i', 'd')) OR
+ (p1.typstorage not in ('p', 'x', 'e', 'm'));
oid | typname
-----+---------
(0 rows)
@@ -91,27 +90,59 @@ WHERE p1.typtype != 'c' AND
(0 rows)
-- Check for bogus typinput routines
--- FIXME: ought to check prorettype, but there are special cases that make it
--- hard: prorettype might be binary-compatible with the type but not the same,
--- and for array types array_in's result has nothing to do with anything.
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
-WHERE p1.typinput = p2.oid AND p1.typtype = 'b' AND
- (p2.pronargs != 1 OR p2.proretset) AND
- (p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
+WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ ((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR
+ (p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND
+ p2.proargtypes[1] = 'oid'::regtype AND
+ p2.proargtypes[2] = 'int4'::regtype));
+ oid | typname | oid | proname
+-----+---------+-----+---------
+(0 rows)
+
+-- As of 7.3, this check finds SET and refcursor, which are borrowing
+-- other types' I/O routines
+SELECT p1.oid, p1.typname, p2.oid, p2.proname
+FROM pg_type AS p1, pg_proc AS p2
+WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ (p1.typelem != 0 AND p1.typlen < 0) AND NOT
+ (p2.prorettype = p1.oid AND NOT p2.proretset);
+ oid | typname | oid | proname
+------+-----------+-----+-----------
+ 32 | SET | 109 | unknownin
+ 1790 | refcursor | 46 | textin
+(2 rows)
+
+-- Varlena array types will point to array_in
+SELECT p1.oid, p1.typname, p2.oid, p2.proname
+FROM pg_type AS p1, pg_proc AS p2
+WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
+ (p1.typelem != 0 AND p1.typlen < 0) AND NOT
+ (p2.oid = 'array_in'::regproc);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
-- Check for bogus typoutput routines
--- The first OR subclause detects bogus non-array cases,
--- the second one detects bogus array cases.
--- FIXME: ought to check prorettype, but not clear what it should be.
+-- As of 7.3, this check finds SET and refcursor, which are borrowing
+-- other types' I/O routines
+SELECT p1.oid, p1.typname, p2.oid, p2.proname
+FROM pg_type AS p1, pg_proc AS p2
+WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ ((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR
+ (p2.oid = 'array_out'::regproc AND
+ p1.typelem != 0));
+ oid | typname | oid | proname
+------+-----------+-----+------------
+ 32 | SET | 110 | unknownout
+ 1790 | refcursor | 47 | textout
+(2 rows)
+
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
-WHERE p1.typoutput = p2.oid AND p1.typtype = 'b' AND
- (p2.pronargs != 1 OR p2.proretset) AND
- (p2.pronargs != 2 OR p2.proretset OR p1.typelem = 0);
+WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ (p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
oid | typname | oid | proname
-----+---------+-----+---------
(0 rows)
diff --git a/src/test/regress/input/create_function_1.source b/src/test/regress/input/create_function_1.source
index 14ae6ff2bbb..f657e3740cd 100644
--- a/src/test/regress/input/create_function_1.source
+++ b/src/test/regress/input/create_function_1.source
@@ -2,38 +2,48 @@
-- CREATE_FUNCTION_1
--
-CREATE FUNCTION widget_in(opaque)
+CREATE FUNCTION widget_in(cstring)
RETURNS widget
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c';
-CREATE FUNCTION widget_out(opaque)
- RETURNS opaque
+CREATE FUNCTION widget_out(widget)
+ RETURNS cstring
+ AS '@abs_builddir@/regress@DLSUFFIX@'
+ LANGUAGE 'c';
+
+CREATE FUNCTION int44in(cstring)
+ RETURNS city_budget
+ AS '@abs_builddir@/regress@DLSUFFIX@'
+ LANGUAGE 'c';
+
+CREATE FUNCTION int44out(city_budget)
+ RETURNS cstring
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c';
CREATE FUNCTION check_primary_key ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION check_foreign_key ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION autoinc ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/autoinc@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION funny_dup17 ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION ttdummy ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'C';
diff --git a/src/test/regress/output/create_function_1.source b/src/test/regress/output/create_function_1.source
index 2c98b6c2eac..9632114f93c 100644
--- a/src/test/regress/output/create_function_1.source
+++ b/src/test/regress/output/create_function_1.source
@@ -1,33 +1,44 @@
--
-- CREATE_FUNCTION_1
--
-CREATE FUNCTION widget_in(opaque)
+CREATE FUNCTION widget_in(cstring)
RETURNS widget
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c';
WARNING: ProcedureCreate: type widget is not yet defined
-CREATE FUNCTION widget_out(opaque)
- RETURNS opaque
+CREATE FUNCTION widget_out(widget)
+ RETURNS cstring
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'c';
+WARNING: Argument type "widget" is only a shell
+CREATE FUNCTION int44in(cstring)
+ RETURNS city_budget
+ AS '@abs_builddir@/regress@DLSUFFIX@'
+ LANGUAGE 'c';
+WARNING: ProcedureCreate: type city_budget is not yet defined
+CREATE FUNCTION int44out(city_budget)
+ RETURNS cstring
+ AS '@abs_builddir@/regress@DLSUFFIX@'
+ LANGUAGE 'c';
+WARNING: Argument type "city_budget" is only a shell
CREATE FUNCTION check_primary_key ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION check_foreign_key ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/refint@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION autoinc ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/../../../contrib/spi/autoinc@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION funny_dup17 ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION ttdummy ()
- RETURNS opaque
+ RETURNS trigger
AS '@abs_builddir@/regress@DLSUFFIX@'
LANGUAGE 'C';
CREATE FUNCTION set_ttdummy (int4)
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index 3ef2c1b6db7..2965dca69de 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -1,5 +1,5 @@
/*
- * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.50 2002/03/06 06:10:50 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.51 2002/08/22 00:01:51 tgl Exp $
*/
#include "postgres.h"
@@ -26,6 +26,8 @@ extern Datum overpaid(PG_FUNCTION_ARGS);
extern Datum boxarea(PG_FUNCTION_ARGS);
extern char *reverse_name(char *string);
extern int oldstyle_length(int n, text *t);
+extern Datum int44in(PG_FUNCTION_ARGS);
+extern Datum int44out(PG_FUNCTION_ARGS);
/*
** Distance from a point to a path
@@ -684,3 +686,61 @@ set_ttdummy(PG_FUNCTION_ARGS)
PG_RETURN_INT32(1);
}
+
+
+/*
+ * Type int44 has no real-world use, but the regression tests use it.
+ * It's a four-element vector of int4's.
+ */
+
+/*
+ * int44in - converts "num num ..." to internal form
+ *
+ * Note: Fills any missing positions with zeroes.
+ */
+PG_FUNCTION_INFO_V1(int44in);
+
+Datum
+int44in(PG_FUNCTION_ARGS)
+{
+ char *input_string = PG_GETARG_CSTRING(0);
+ int32 *result = (int32 *) palloc(4 * sizeof(int32));
+ int i;
+
+ i = sscanf(input_string,
+ "%d, %d, %d, %d",
+ &result[0],
+ &result[1],
+ &result[2],
+ &result[3]);
+ while (i < 4)
+ result[i++] = 0;
+
+ PG_RETURN_POINTER(result);
+}
+
+/*
+ * int44out - converts internal form to "num num ..."
+ */
+PG_FUNCTION_INFO_V1(int44out);
+
+Datum
+int44out(PG_FUNCTION_ARGS)
+{
+ int32 *an_array = (int32 *) PG_GETARG_POINTER(0);
+ char *result = (char *) palloc(16 * 4); /* Allow 14 digits +
+ * sign */
+ int i;
+ char *walk;
+
+ walk = result;
+ for (i = 0; i < 4; i++)
+ {
+ pg_ltoa(an_array[i], walk);
+ while (*++walk != '\0')
+ ;
+ *walk++ = ' ';
+ }
+ *--walk = '\0';
+ PG_RETURN_CSTRING(result);
+}
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index 4f0d50247f1..72c52dba113 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -6,14 +6,14 @@ CREATE TABLE x (
e text
);
-CREATE FUNCTION fn_x_before () RETURNS OPAQUE AS '
+CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
BEGIN
NEW.e := ''before trigger fired''::text;
return NEW;
END;
' language 'plpgsql';
-CREATE FUNCTION fn_x_after () RETURNS OPAQUE AS '
+CREATE FUNCTION fn_x_after () RETURNS TRIGGER AS '
BEGIN
UPDATE x set e=''after trigger fired'' where c=''stuff'';
return NULL;
diff --git a/src/test/regress/sql/create_type.sql b/src/test/regress/sql/create_type.sql
index 9b37981bd49..ddcba72624e 100644
--- a/src/test/regress/sql/create_type.sql
+++ b/src/test/regress/sql/create_type.sql
@@ -18,10 +18,28 @@ CREATE TYPE city_budget (
-- Test type-related default values (broken in releases before PG 7.2)
+-- Make dummy I/O routines using the existing internal support for int4, text
+CREATE FUNCTION int42_in(cstring)
+ RETURNS int42
+ AS 'int4in'
+ LANGUAGE 'internal' WITH (isStrict);
+CREATE FUNCTION int42_out(int42)
+ RETURNS cstring
+ AS 'int4out'
+ LANGUAGE 'internal' WITH (isStrict);
+CREATE FUNCTION text_w_default_in(cstring)
+ RETURNS text_w_default
+ AS 'textin'
+ LANGUAGE 'internal' WITH (isStrict);
+CREATE FUNCTION text_w_default_out(text_w_default)
+ RETURNS cstring
+ AS 'textout'
+ LANGUAGE 'internal' WITH (isStrict);
+
CREATE TYPE int42 (
internallength = 4,
- input = int4in,
- output = int4out,
+ input = int42_in,
+ output = int42_out,
alignment = int4,
default = 42,
passedbyvalue
@@ -29,8 +47,8 @@ CREATE TYPE int42 (
CREATE TYPE text_w_default (
internallength = variable,
- input = textin,
- output = textout,
+ input = text_w_default_in,
+ output = text_w_default_out,
alignment = int4,
default = 'zippo'
);
diff --git a/src/test/regress/sql/drop.sql b/src/test/regress/sql/drop.sql
index a466e6f7c21..2b143d95bc7 100644
--- a/src/test/regress/sql/drop.sql
+++ b/src/test/regress/sql/drop.sql
@@ -24,9 +24,9 @@ DROP FUNCTION equipment(hobbies_r);
DROP FUNCTION user_relns();
-DROP FUNCTION widget_in(opaque);
+DROP FUNCTION widget_in(cstring);
-DROP FUNCTION widget_out(opaque);
+DROP FUNCTION widget_out(widget);
DROP FUNCTION pt_in_widget(point,widget);
diff --git a/src/test/regress/sql/opr_sanity.sql b/src/test/regress/sql/opr_sanity.sql
index 9d08dbd5bb3..d9be98a5fd3 100644
--- a/src/test/regress/sql/opr_sanity.sql
+++ b/src/test/regress/sql/opr_sanity.sql
@@ -18,17 +18,24 @@
-- **************** pg_proc ****************
-- Look for illegal values in pg_proc fields.
--- NOTE: currently there are a few pg_proc entries that have prorettype = 0.
--- Someday that ought to be cleaned up.
+-- NOTE: in reality pronargs could be more than 10, but I'm too lazy to put
+-- a larger number of proargtypes check clauses in here. If we ever have
+-- more-than-10-arg functions in the standard catalogs, extend this query.
SELECT p1.oid, p1.proname
FROM pg_proc as p1
-WHERE (p1.prolang = 0 OR p1.prorettype = 0 OR
- p1.pronargs < 0 OR p1.pronargs > 16)
- AND p1.proname !~ '^pl[^_]+_call_handler$'
- AND p1.proname !~ '^RI_FKey_'
- AND p1.proname !~ 'costestimate$'
- AND p1.proname != 'update_pg_pwd_and_pg_group';
+WHERE p1.prolang = 0 OR p1.prorettype = 0 OR
+ p1.pronargs < 0 OR p1.pronargs > 10 OR
+ (p1.proargtypes[0] = 0 AND p1.pronargs > 0) OR
+ (p1.proargtypes[1] = 0 AND p1.pronargs > 1) OR
+ (p1.proargtypes[2] = 0 AND p1.pronargs > 2) OR
+ (p1.proargtypes[3] = 0 AND p1.pronargs > 3) OR
+ (p1.proargtypes[4] = 0 AND p1.pronargs > 4) OR
+ (p1.proargtypes[5] = 0 AND p1.pronargs > 5) OR
+ (p1.proargtypes[6] = 0 AND p1.pronargs > 6) OR
+ (p1.proargtypes[7] = 0 AND p1.pronargs > 7) OR
+ (p1.proargtypes[8] = 0 AND p1.pronargs > 8) OR
+ (p1.proargtypes[9] = 0 AND p1.pronargs > 9);
-- Look for conflicting proc definitions (same names and input datatypes).
-- (This test should be dead code now that we have the unique index
@@ -174,7 +181,7 @@ WHERE c.castfunc = 0 AND NOT c.castimplicit;
SELECT *
FROM pg_cast c
WHERE c.castfunc = 0 AND
- NOT EXISTS (SELECT * FROM pg_cast k
+ NOT EXISTS (SELECT 1 FROM pg_cast k
WHERE k.castfunc = 0 AND
k.castsource = c.casttarget AND
k.casttarget = c.castsource);
@@ -279,7 +286,7 @@ WHERE p1.oprlsortop != 0 AND
SELECT p1.oid, p1.oprname FROM pg_operator AS p1
WHERE p1.oprlsortop != 0 AND NOT
- EXISTS(SELECT * FROM pg_operator AS p2 WHERE
+ EXISTS(SELECT 1 FROM pg_operator AS p2 WHERE
p2.oprname = '<' AND
p2.oprleft = p1.oprleft AND
p2.oprright = p1.oprright AND
@@ -287,7 +294,7 @@ WHERE p1.oprlsortop != 0 AND NOT
SELECT p1.oid, p1.oprname FROM pg_operator AS p1
WHERE p1.oprlsortop != 0 AND NOT
- EXISTS(SELECT * FROM pg_operator AS p2 WHERE
+ EXISTS(SELECT 1 FROM pg_operator AS p2 WHERE
p2.oprname = '>' AND
p2.oprleft = p1.oprleft AND
p2.oprright = p1.oprright AND
@@ -386,7 +393,7 @@ WHERE p1.oprcode = p2.oid AND
-- If oprrest is set, the operator must return boolean,
-- and it must link to a proc with the right signature
-- to be a restriction selectivity estimator.
--- The proc signature we want is: float8 proc(opaque, oid, opaque, int4)
+-- The proc signature we want is: float8 proc(internal, oid, internal, int4)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
@@ -394,13 +401,15 @@ WHERE p1.oprrest = p2.oid AND
(p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 4 OR
- p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
- p2.proargtypes[2] != 0 OR p2.proargtypes[3] != 'int4'::regtype);
+ p2.proargtypes[0] != 'internal'::regtype OR
+ p2.proargtypes[1] != 'oid'::regtype OR
+ p2.proargtypes[2] != 'internal'::regtype OR
+ p2.proargtypes[3] != 'int4'::regtype);
-- If oprjoin is set, the operator must be a binary boolean op,
-- and it must link to a proc with the right signature
-- to be a join selectivity estimator.
--- The proc signature we want is: float8 proc(opaque, oid, opaque)
+-- The proc signature we want is: float8 proc(internal, oid, internal)
SELECT p1.oid, p1.oprname, p2.oid, p2.proname
FROM pg_operator AS p1, pg_proc AS p2
@@ -408,8 +417,9 @@ WHERE p1.oprjoin = p2.oid AND
(p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR
p2.prorettype != 'float8'::regtype OR p2.proretset OR
p2.pronargs != 3 OR
- p2.proargtypes[0] != 0 OR p2.proargtypes[1] != 'oid'::regtype OR
- p2.proargtypes[2] != 0);
+ p2.proargtypes[0] != 'internal'::regtype OR
+ p2.proargtypes[1] != 'oid'::regtype OR
+ p2.proargtypes[2] != 'internal'::regtype);
-- **************** pg_aggregate ****************
@@ -454,7 +464,7 @@ WHERE a.aggfnoid = p.oid AND
a.aggtranstype != p2.prorettype OR
a.aggtranstype != p2.proargtypes[0] OR
NOT ((p2.pronargs = 2 AND p.proargtypes[0] = p2.proargtypes[1]) OR
- (p2.pronargs = 1 AND p.proargtypes[0] = 0)));
+ (p2.pronargs = 1 AND p.proargtypes[0] = '"any"'::regtype)));
-- Cross-check finalfn (if present) against its entry in pg_proc.
-- FIXME: what about binary-compatible types?
diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql
index 618273823b3..2f967c65ce4 100644
--- a/src/test/regress/sql/plpgsql.sql
+++ b/src/test/regress/sql/plpgsql.sql
@@ -107,7 +107,7 @@ create unique index PHone_name on PHone using btree (slotname bpchar_ops);
-- * AFTER UPDATE on Room
-- * - If room no changes let wall slots follow
-- ************************************************************
-create function tg_room_au() returns opaque as '
+create function tg_room_au() returns trigger as '
begin
if new.roomno != old.roomno then
update WSlot set roomno = new.roomno where roomno = old.roomno;
@@ -124,7 +124,7 @@ create trigger tg_room_au after update
-- * AFTER DELETE on Room
-- * - delete wall slots in this room
-- ************************************************************
-create function tg_room_ad() returns opaque as '
+create function tg_room_ad() returns trigger as '
begin
delete from WSlot where roomno = old.roomno;
return old;
@@ -139,7 +139,7 @@ create trigger tg_room_ad after delete
-- * BEFORE INSERT or UPDATE on WSlot
-- * - Check that room exists
-- ************************************************************
-create function tg_wslot_biu() returns opaque as '
+create function tg_wslot_biu() returns trigger as '
begin
if count(*) = 0 from Room where roomno = new.roomno then
raise exception ''Room % does not exist'', new.roomno;
@@ -156,7 +156,7 @@ create trigger tg_wslot_biu before insert or update
-- * AFTER UPDATE on PField
-- * - Let PSlots of this field follow
-- ************************************************************
-create function tg_pfield_au() returns opaque as '
+create function tg_pfield_au() returns trigger as '
begin
if new.name != old.name then
update PSlot set pfname = new.name where pfname = old.name;
@@ -173,7 +173,7 @@ create trigger tg_pfield_au after update
-- * AFTER DELETE on PField
-- * - Remove all slots of this patchfield
-- ************************************************************
-create function tg_pfield_ad() returns opaque as '
+create function tg_pfield_ad() returns trigger as '
begin
delete from PSlot where pfname = old.name;
return old;
@@ -188,7 +188,7 @@ create trigger tg_pfield_ad after delete
-- * BEFORE INSERT or UPDATE on PSlot
-- * - Ensure that our patchfield does exist
-- ************************************************************
-create function tg_pslot_biu() returns opaque as '
+create function tg_pslot_biu() returns trigger as '
declare
pfrec record;
rename new to ps;
@@ -209,7 +209,7 @@ create trigger tg_pslot_biu before insert or update
-- * AFTER UPDATE on System
-- * - If system name changes let interfaces follow
-- ************************************************************
-create function tg_system_au() returns opaque as '
+create function tg_system_au() returns trigger as '
begin
if new.name != old.name then
update IFace set sysname = new.name where sysname = old.name;
@@ -226,7 +226,7 @@ create trigger tg_system_au after update
-- * BEFORE INSERT or UPDATE on IFace
-- * - set the slotname to IF.sysname.ifname
-- ************************************************************
-create function tg_iface_biu() returns opaque as '
+create function tg_iface_biu() returns trigger as '
declare
sname text;
sysrec record;
@@ -254,7 +254,7 @@ create trigger tg_iface_biu before insert or update
-- * AFTER INSERT or UPDATE or DELETE on Hub
-- * - insert/delete/rename slots as required
-- ************************************************************
-create function tg_hub_a() returns opaque as '
+create function tg_hub_a() returns trigger as '
declare
hname text;
dummy integer;
@@ -312,7 +312,7 @@ end;
-- * - prevent from manual manipulation
-- * - set the slotname to HS.hubname.slotno
-- ************************************************************
-create function tg_hslot_biu() returns opaque as '
+create function tg_hslot_biu() returns trigger as '
declare
sname text;
xname HSlot.slotname%TYPE;
@@ -351,7 +351,7 @@ create trigger tg_hslot_biu before insert or update
-- * BEFORE DELETE on HSlot
-- * - prevent from manual manipulation
-- ************************************************************
-create function tg_hslot_bd() returns opaque as '
+create function tg_hslot_bd() returns trigger as '
declare
hubrec record;
begin
@@ -374,7 +374,7 @@ create trigger tg_hslot_bd before delete
-- * BEFORE INSERT on all slots
-- * - Check name prefix
-- ************************************************************
-create function tg_chkslotname() returns opaque as '
+create function tg_chkslotname() returns trigger as '
begin
if substr(new.slotname, 1, 2) != tg_argv[0] then
raise exception ''slotname must begin with %'', tg_argv[0];
@@ -403,7 +403,7 @@ create trigger tg_chkslotname before insert
-- * BEFORE INSERT or UPDATE on all slots with slotlink
-- * - Set slotlink to empty string if NULL value given
-- ************************************************************
-create function tg_chkslotlink() returns opaque as '
+create function tg_chkslotlink() returns trigger as '
begin
if new.slotlink isnull then
new.slotlink := '''';
@@ -432,7 +432,7 @@ create trigger tg_chkslotlink before insert or update
-- * BEFORE INSERT or UPDATE on all slots with backlink
-- * - Set backlink to empty string if NULL value given
-- ************************************************************
-create function tg_chkbacklink() returns opaque as '
+create function tg_chkbacklink() returns trigger as '
begin
if new.backlink isnull then
new.backlink := '''';
@@ -455,7 +455,7 @@ create trigger tg_chkbacklink before insert or update
-- * BEFORE UPDATE on PSlot
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_pslot_bu() returns opaque as '
+create function tg_pslot_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from PSlot where slotname = old.slotname;
@@ -484,7 +484,7 @@ create trigger tg_pslot_bu before update
-- * BEFORE UPDATE on WSlot
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_wslot_bu() returns opaque as '
+create function tg_wslot_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from WSlot where slotname = old.slotname;
@@ -513,7 +513,7 @@ create trigger tg_wslot_bu before update
-- * BEFORE UPDATE on PLine
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_pline_bu() returns opaque as '
+create function tg_pline_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from PLine where slotname = old.slotname;
@@ -542,7 +542,7 @@ create trigger tg_pline_bu before update
-- * BEFORE UPDATE on IFace
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_iface_bu() returns opaque as '
+create function tg_iface_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from IFace where slotname = old.slotname;
@@ -571,7 +571,7 @@ create trigger tg_iface_bu before update
-- * BEFORE UPDATE on HSlot
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_hslot_bu() returns opaque as '
+create function tg_hslot_bu() returns trigger as '
begin
if new.slotname != old.slotname or new.hubname != old.hubname then
delete from HSlot where slotname = old.slotname;
@@ -600,7 +600,7 @@ create trigger tg_hslot_bu before update
-- * BEFORE UPDATE on PHone
-- * - do delete/insert instead of update if name changes
-- ************************************************************
-create function tg_phone_bu() returns opaque as '
+create function tg_phone_bu() returns trigger as '
begin
if new.slotname != old.slotname then
delete from PHone where slotname = old.slotname;
@@ -627,7 +627,7 @@ create trigger tg_phone_bu before update
-- * AFTER INSERT or UPDATE or DELETE on slot with backlink
-- * - Ensure that the opponent correctly points back to us
-- ************************************************************
-create function tg_backlink_a() returns opaque as '
+create function tg_backlink_a() returns trigger as '
declare
dummy integer;
begin
@@ -781,7 +781,7 @@ end;
-- * AFTER INSERT or UPDATE or DELETE on slot with slotlink
-- * - Ensure that the opponent correctly points back to us
-- ************************************************************
-create function tg_slotlink_a() returns opaque as '
+create function tg_slotlink_a() returns trigger as '
declare
dummy integer;
begin
diff --git a/src/test/regress/sql/type_sanity.sql b/src/test/regress/sql/type_sanity.sql
index 5003ae6b165..0a9701de827 100644
--- a/src/test/regress/sql/type_sanity.sql
+++ b/src/test/regress/sql/type_sanity.sql
@@ -18,13 +18,12 @@
SELECT p1.oid, p1.typname
FROM pg_type as p1
-WHERE (p1.typlen <= 0 AND p1.typlen != -1) OR
- p1.typtype not in('b', 'c', 'd', 'p') OR
+WHERE p1.typnamespace = 0 OR
+ (p1.typlen <= 0 AND p1.typlen != -1) OR
+ (p1.typtype not in ('b', 'c', 'd', 'p')) OR
NOT p1.typisdefined OR
- (p1.typalign != 'c' AND p1.typalign != 's' AND
- p1.typalign != 'i' AND p1.typalign != 'd') OR
- (p1.typstorage != 'p' AND p1.typstorage != 'x' AND
- p1.typstorage != 'e' AND p1.typstorage != 'm');
+ (p1.typalign not in ('c', 's', 'i', 'd')) OR
+ (p1.typstorage not in ('p', 'x', 'e', 'm'));
-- Look for "pass by value" types that can't be passed by value.
@@ -76,26 +75,45 @@ WHERE p1.typtype != 'c' AND
(p1.typinput = 0 OR p1.typoutput = 0);
-- Check for bogus typinput routines
--- FIXME: ought to check prorettype, but there are special cases that make it
--- hard: prorettype might be binary-compatible with the type but not the same,
--- and for array types array_in's result has nothing to do with anything.
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
-WHERE p1.typinput = p2.oid AND p1.typtype = 'b' AND
- (p2.pronargs != 1 OR p2.proretset) AND
- (p2.pronargs != 3 OR p2.proretset OR p2.proargtypes[2] != 'int4'::regtype);
+WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ ((p2.pronargs = 1 AND p2.proargtypes[0] = 'cstring'::regtype) OR
+ (p2.pronargs = 3 AND p2.proargtypes[0] = 'cstring'::regtype AND
+ p2.proargtypes[1] = 'oid'::regtype AND
+ p2.proargtypes[2] = 'int4'::regtype));
+
+-- As of 7.3, this check finds SET and refcursor, which are borrowing
+-- other types' I/O routines
+SELECT p1.oid, p1.typname, p2.oid, p2.proname
+FROM pg_type AS p1, pg_proc AS p2
+WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ (p1.typelem != 0 AND p1.typlen < 0) AND NOT
+ (p2.prorettype = p1.oid AND NOT p2.proretset);
+
+-- Varlena array types will point to array_in
+SELECT p1.oid, p1.typname, p2.oid, p2.proname
+FROM pg_type AS p1, pg_proc AS p2
+WHERE p1.typinput = p2.oid AND p1.typtype in ('b', 'p') AND
+ (p1.typelem != 0 AND p1.typlen < 0) AND NOT
+ (p2.oid = 'array_in'::regproc);
-- Check for bogus typoutput routines
--- The first OR subclause detects bogus non-array cases,
--- the second one detects bogus array cases.
--- FIXME: ought to check prorettype, but not clear what it should be.
+
+-- As of 7.3, this check finds SET and refcursor, which are borrowing
+-- other types' I/O routines
+SELECT p1.oid, p1.typname, p2.oid, p2.proname
+FROM pg_type AS p1, pg_proc AS p2
+WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ ((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR
+ (p2.oid = 'array_out'::regproc AND
+ p1.typelem != 0));
SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2
-WHERE p1.typoutput = p2.oid AND p1.typtype = 'b' AND
- (p2.pronargs != 1 OR p2.proretset) AND
- (p2.pronargs != 2 OR p2.proretset OR p1.typelem = 0);
+WHERE p1.typoutput = p2.oid AND p1.typtype in ('b', 'p') AND NOT
+ (p2.prorettype = 'cstring'::regtype AND NOT p2.proretset);
-- **************** pg_class ****************