mirror of
https://github.com/postgres/postgres.git
synced 2025-12-07 12:02:30 +03:00
Restructure representation of aggregate functions so that they have pg_proc
entries, per pghackers discussion. This fixes aggregates to live in namespaces, and also simplifies/speeds up lookup in parse_func.c. Also, add a 'proimplicit' flag to pg_proc that controls whether a type coercion function may be invoked implicitly, or only explicitly. The current settings of these flags are more permissive than I would like, but we will need to debate and refine the behavior; for now, I avoided breaking regression tests as much as I could.
This commit is contained in:
@@ -292,8 +292,8 @@ ALTER TABLE foo_seq RENAME TO foo_seq_new;
|
||||
SELECT * FROM foo_seq_new;
|
||||
sequence_name | last_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
|
||||
---------------+------------+--------------+---------------------+-----------+-------------+---------+-----------+-----------
|
||||
foo_seq | 1 | 1 | 9223372036854775807 | 1 | 1 | 1 | f | f
|
||||
(1 row)
|
||||
foo_seq | 1 | 1 | 9223372036854775807 | 1 | 1 | 1 | f | f
|
||||
(1 row)
|
||||
|
||||
DROP SEQUENCE foo_seq_new;
|
||||
-- FOREIGN KEY CONSTRAINT adding TEST
|
||||
@@ -345,17 +345,17 @@ DROP TABLE tmp2;
|
||||
-- is run in parallel with foreign_key.sql.
|
||||
CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 text);
|
||||
-- This next should fail, because text=int does not exist
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 inet);
|
||||
-- This next should fail, because inet=int does not exist
|
||||
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
|
||||
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This should also fail for the same reason, but here we
|
||||
-- give the column name
|
||||
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
|
||||
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This should succeed, even though they are different types
|
||||
-- because varchar=int does exist
|
||||
@@ -370,7 +370,7 @@ DROP TABLE pktable;
|
||||
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
|
||||
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "fktable"
|
||||
DROP TABLE fktable;
|
||||
CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 text,
|
||||
CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
|
||||
PRIMARY KEY(ptest1, ptest2));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
-- This should fail, because we just chose really odd types
|
||||
@@ -389,17 +389,17 @@ ERROR: Unable to identify an operator '=' for types 'cidr' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This fails because we mixed up the column ordering
|
||||
DROP TABLE FKTABLE;
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 text);
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet);
|
||||
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
|
||||
references pktable(ptest2, ptest1);
|
||||
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'text'
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'inet'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- As does this...
|
||||
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest2, ftest1)
|
||||
references pktable(ptest1, ptest2);
|
||||
NOTICE: ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- temp tables should go away by themselves, need not drop them.
|
||||
-- test check constraint adding
|
||||
|
||||
@@ -718,16 +718,16 @@ DROP TABLE PKTABLE;
|
||||
-- Basic one column, two table setup
|
||||
CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
-- This next should fail, because text=int does not exist
|
||||
CREATE TABLE FKTABLE (ftest1 text REFERENCES pktable);
|
||||
-- This next should fail, because inet=int does not exist
|
||||
CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable);
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This should also fail for the same reason, but here we
|
||||
-- give the column name
|
||||
CREATE TABLE FKTABLE (ftest1 text REFERENCES pktable(ptest1));
|
||||
CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This should succeed, even though they are different types
|
||||
-- because varchar=int does exist
|
||||
@@ -744,7 +744,7 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p
|
||||
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
|
||||
DROP TABLE PKTABLE;
|
||||
-- Two columns, two tables
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, PRIMARY KEY(ptest1, ptest2));
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
-- This should fail, because we just chose really odd types
|
||||
CREATE TABLE FKTABLE (ftest1 cidr, ftest2 datetime, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable);
|
||||
@@ -757,28 +757,28 @@ NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'cidr' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This fails because we mixed up the column ordering
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable);
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable);
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- As does this...
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- And again..
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'text'
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'inet'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- This works...
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
DROP TABLE FKTABLE;
|
||||
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
|
||||
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
|
||||
-- As does this
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
DROP TABLE FKTABLE;
|
||||
NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "pktable"
|
||||
@@ -786,37 +786,37 @@ NOTICE: DROP TABLE implicitly drops referential integrity trigger from table "p
|
||||
DROP TABLE PKTABLE;
|
||||
-- Two columns, same table
|
||||
-- Make sure this still works...
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
ptest4) REFERENCES pktable(ptest1, ptest2));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
DROP TABLE PKTABLE;
|
||||
-- And this,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
ptest4) REFERENCES pktable);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
DROP TABLE PKTABLE;
|
||||
-- This shouldn't (mixed up columns)
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
ptest4) REFERENCES pktable(ptest2, ptest1));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'text'
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'inet'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
ptest3) REFERENCES pktable(ptest1, ptest2));
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- Not this one either... Same as the last one except we didn't defined the columns being referenced.
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
ptest3) REFERENCES pktable);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
--
|
||||
-- Now some cases with inheritance
|
||||
@@ -907,7 +907,7 @@ drop table pktable;
|
||||
drop table pktable_base;
|
||||
-- 2 columns (2 tables), mismatched types
|
||||
create table pktable_base(base1 int not null);
|
||||
create table pktable(ptest1 text, primary key(base1, ptest1)) inherits (pktable_base);
|
||||
create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
-- just generally bad types (with and without column references on the referenced table)
|
||||
create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable);
|
||||
@@ -919,45 +919,45 @@ NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'cidr' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
-- let's mix up which columns reference which
|
||||
create table fktable(ftest1 int, ftest2 text, foreign key(ftest2, ftest1) references pktable);
|
||||
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable);
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
create table fktable(ftest1 int, ftest2 text, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
|
||||
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
create table fktable(ftest1 int, ftest2 text, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
|
||||
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'text'
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'inet'
|
||||
You will have to retype this query using an explicit cast
|
||||
drop table pktable;
|
||||
drop table pktable_base;
|
||||
-- 2 columns (1 table), mismatched types
|
||||
create table pktable_base(base1 int not null, base2 int);
|
||||
create table pktable(ptest1 text, ptest2 text[], primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
pktable(base1, ptest1)) inherits (pktable_base);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text[]' and 'text'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet[]' and 'inet'
|
||||
You will have to retype this query using an explicit cast
|
||||
create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
pktable(ptest1, base1)) inherits (pktable_base);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'text'
|
||||
ERROR: Unable to identify an operator '=' for types 'integer' and 'inet'
|
||||
You will have to retype this query using an explicit cast
|
||||
create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
pktable(base1, ptest1)) inherits (pktable_base);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
pktable(base1, ptest1)) inherits (pktable_base);
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index 'pktable_pkey' for table 'pktable'
|
||||
NOTICE: CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
|
||||
ERROR: Unable to identify an operator '=' for types 'text' and 'integer'
|
||||
ERROR: Unable to identify an operator '=' for types 'inet' and 'integer'
|
||||
You will have to retype this query using an explicit cast
|
||||
drop table pktable;
|
||||
ERROR: table "pktable" does not exist
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
--
|
||||
-- This is created by pgsql/contrib/findoidjoins/make_oidjoin_check
|
||||
--
|
||||
SELECT ctid, pg_aggregate.aggfnoid
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggfnoid != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_proc AS t1 WHERE t1.oid = pg_aggregate.aggfnoid);
|
||||
ctid | aggfnoid
|
||||
------+----------
|
||||
(0 rows)
|
||||
|
||||
SELECT ctid, pg_aggregate.aggtransfn
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggtransfn != 0 AND
|
||||
@@ -17,14 +25,6 @@ WHERE pg_aggregate.aggfinalfn != 0 AND
|
||||
------+------------
|
||||
(0 rows)
|
||||
|
||||
SELECT ctid, pg_aggregate.aggbasetype
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggbasetype != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_type AS t1 WHERE t1.oid = pg_aggregate.aggbasetype);
|
||||
ctid | aggbasetype
|
||||
------+-------------
|
||||
(0 rows)
|
||||
|
||||
SELECT ctid, pg_aggregate.aggtranstype
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggtranstype != 0 AND
|
||||
@@ -33,14 +33,6 @@ WHERE pg_aggregate.aggtranstype != 0 AND
|
||||
------+--------------
|
||||
(0 rows)
|
||||
|
||||
SELECT ctid, pg_aggregate.aggfinaltype
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggfinaltype != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_type AS t1 WHERE t1.oid = pg_aggregate.aggfinaltype);
|
||||
ctid | aggfinaltype
|
||||
------+--------------
|
||||
(0 rows)
|
||||
|
||||
SELECT ctid, pg_am.amgettuple
|
||||
FROM pg_am
|
||||
WHERE pg_am.amgettuple != 0 AND
|
||||
|
||||
@@ -48,7 +48,7 @@ WHERE p1.oid != p2.oid AND
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Considering only built-in procs (prolang = 11/12), look for multiple uses
|
||||
-- Considering only built-in procs (prolang = 12), look for multiple uses
|
||||
-- of the same internal function (ie, matching prosrc fields). It's OK to
|
||||
-- have several entries with different pronames for the same internal function,
|
||||
-- but conflicts in the number of arguments and other critical items should
|
||||
@@ -57,14 +57,14 @@ SELECT p1.oid, p1.proname, p2.oid, p2.proname
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
(p1.prolang != p2.prolang OR
|
||||
p1.proisinh != p2.proisinh OR
|
||||
p1.proisagg != p2.proisagg OR
|
||||
p1.proistrusted != p2.proistrusted OR
|
||||
p1.proisstrict != p2.proisstrict OR
|
||||
p1.proretset != p2.proretset OR
|
||||
p1.provolatile != p2.provolatile OR
|
||||
p1.pronargs != p2.pronargs OR
|
||||
p1.proretset != p2.proretset);
|
||||
p1.pronargs != p2.pronargs);
|
||||
oid | proname | oid | proname
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
@@ -75,12 +75,14 @@ WHERE p1.oid != p2.oid AND
|
||||
-- That's not wrong, necessarily, but we make lists of all the types being
|
||||
-- so treated. Note that the expected output of this part of the test will
|
||||
-- need to be modified whenever new pairs of types are made binary-equivalent!
|
||||
-- Note: ignore aggregate functions here, since they all point to the same
|
||||
-- dummy built-in function.
|
||||
SELECT DISTINCT p1.prorettype, p2.prorettype
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.prorettype < p2.prorettype);
|
||||
prorettype | prorettype
|
||||
------------+------------
|
||||
@@ -92,8 +94,8 @@ SELECT DISTINCT p1.proargtypes[0], p2.proargtypes[0]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[0] < p2.proargtypes[0]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -106,8 +108,8 @@ SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[1] < p2.proargtypes[1]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -119,8 +121,8 @@ SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[2] < p2.proargtypes[2]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -131,8 +133,8 @@ SELECT DISTINCT p1.proargtypes[3], p2.proargtypes[3]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[3] < p2.proargtypes[3]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -143,8 +145,8 @@ SELECT DISTINCT p1.proargtypes[4], p2.proargtypes[4]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[4] < p2.proargtypes[4]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -154,8 +156,8 @@ SELECT DISTINCT p1.proargtypes[5], p2.proargtypes[5]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[5] < p2.proargtypes[5]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -165,8 +167,8 @@ SELECT DISTINCT p1.proargtypes[6], p2.proargtypes[6]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[6] < p2.proargtypes[6]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
@@ -176,13 +178,29 @@ SELECT DISTINCT p1.proargtypes[7], p2.proargtypes[7]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[7] < p2.proargtypes[7]);
|
||||
proargtypes | proargtypes
|
||||
-------------+-------------
|
||||
(0 rows)
|
||||
|
||||
-- If a proc is marked as an implicit cast, then it should be something that
|
||||
-- the system might actually use as a cast function: name same as the name
|
||||
-- of its output type, and either one arg that's a different type, or two
|
||||
-- args where the first is the same as the output type and the second is int4.
|
||||
SELECT p1.oid, p1.proname
|
||||
FROM pg_proc as p1
|
||||
WHERE p1.proimplicit AND
|
||||
(NOT EXISTS (SELECT 1 FROM pg_type t WHERE t.oid = p1.prorettype AND
|
||||
t.typname = p1.proname) OR
|
||||
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
|
||||
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
|
||||
p1.proargtypes[1] = 23)));
|
||||
oid | proname
|
||||
-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- **************** pg_operator ****************
|
||||
-- Look for illegal values in pg_operator fields.
|
||||
SELECT p1.oid, p1.oprname
|
||||
@@ -238,6 +256,7 @@ WHERE p1.oprcom = p2.oid AND
|
||||
-- single-operand operators.
|
||||
-- We expect that B will always say that B.oprnegate = A as well; that's not
|
||||
-- inherently essential, but it would be inefficient not to mark it so.
|
||||
-- Also, A and B had better not be the same operator.
|
||||
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
|
||||
FROM pg_operator AS p1, pg_operator AS p2
|
||||
WHERE p1.oprnegate = p2.oid AND
|
||||
@@ -246,7 +265,8 @@ WHERE p1.oprnegate = p2.oid AND
|
||||
p1.oprright != p2.oprright OR
|
||||
p1.oprresult != 16 OR
|
||||
p2.oprresult != 16 OR
|
||||
p1.oid != p2.oprnegate);
|
||||
p1.oid != p2.oprnegate OR
|
||||
p1.oid = p2.oid);
|
||||
oid | oprcode | oid | oprcode
|
||||
-----+---------+-----+---------
|
||||
(0 rows)
|
||||
@@ -455,19 +475,38 @@ WHERE p1.oprjoin = p2.oid AND
|
||||
|
||||
-- **************** pg_aggregate ****************
|
||||
-- Look for illegal values in pg_aggregate fields.
|
||||
SELECT p1.oid, p1.aggname
|
||||
SELECT ctid, aggfnoid::oid
|
||||
FROM pg_aggregate as p1
|
||||
WHERE aggtransfn = 0 OR aggtranstype = 0 OR aggfinaltype = 0;
|
||||
oid | aggname
|
||||
WHERE aggfnoid = 0 OR aggtransfn = 0 OR aggtranstype = 0;
|
||||
ctid | aggfnoid
|
||||
------+----------
|
||||
(0 rows)
|
||||
|
||||
-- Make sure the matching pg_proc entry is sensible, too.
|
||||
SELECT a.aggfnoid::oid, p.proname
|
||||
FROM pg_aggregate as a, pg_proc as p
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
(NOT p.proisagg OR p.pronargs != 1 OR p.proretset);
|
||||
aggfnoid | proname
|
||||
----------+---------
|
||||
(0 rows)
|
||||
|
||||
-- Make sure there are no proisagg pg_proc entries without matches.
|
||||
SELECT oid, proname
|
||||
FROM pg_proc as p
|
||||
WHERE p.proisagg AND
|
||||
NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid);
|
||||
oid | proname
|
||||
-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- If there is no finalfn then the output type must be the transtype.
|
||||
SELECT p1.oid, p1.aggname
|
||||
FROM pg_aggregate as p1
|
||||
WHERE p1.aggfinalfn = 0 AND p1.aggfinaltype != p1.aggtranstype;
|
||||
oid | aggname
|
||||
-----+---------
|
||||
SELECT a.aggfnoid::oid, p.proname
|
||||
FROM pg_aggregate as a, pg_proc as p
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype;
|
||||
aggfnoid | proname
|
||||
----------+---------
|
||||
(0 rows)
|
||||
|
||||
-- Cross-check transfn against its entry in pg_proc.
|
||||
@@ -476,41 +515,44 @@ WHERE p1.aggfinalfn = 0 AND p1.aggfinaltype != p1.aggtranstype;
|
||||
-- implemented using int4larger/int4smaller. Until we have
|
||||
-- some cleaner way of dealing with binary-equivalent types, just leave
|
||||
-- those two tuples in the expected output.
|
||||
SELECT p1.oid, p1.aggname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS p1, pg_proc AS p2
|
||||
WHERE p1.aggtransfn = p2.oid AND
|
||||
SELECT a.aggfnoid::oid, p.proname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS p2
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggtransfn = p2.oid AND
|
||||
(p2.proretset OR
|
||||
p1.aggtranstype != p2.prorettype OR
|
||||
p1.aggtranstype != p2.proargtypes[0] OR
|
||||
NOT ((p2.pronargs = 2 AND p1.aggbasetype = p2.proargtypes[1]) OR
|
||||
(p2.pronargs = 1 AND p1.aggbasetype = 0)));
|
||||
oid | aggname | oid | proname
|
||||
-------+---------+-----+-------------
|
||||
10021 | max | 768 | int4larger
|
||||
10037 | min | 769 | int4smaller
|
||||
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)));
|
||||
aggfnoid | proname | oid | proname
|
||||
----------+---------+-----+-------------
|
||||
2121 | max | 768 | int4larger
|
||||
2137 | min | 769 | int4smaller
|
||||
(2 rows)
|
||||
|
||||
-- Cross-check finalfn (if present) against its entry in pg_proc.
|
||||
-- FIXME: what about binary-compatible types?
|
||||
SELECT p1.oid, p1.aggname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS p1, pg_proc AS p2
|
||||
WHERE p1.aggfinalfn = p2.oid AND
|
||||
(p2.proretset OR p1.aggfinaltype != p2.prorettype OR
|
||||
SELECT a.aggfnoid::oid, p.proname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS p2
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggfinalfn = p2.oid AND
|
||||
(p2.proretset OR p.prorettype != p2.prorettype OR
|
||||
p2.pronargs != 1 OR
|
||||
p1.aggtranstype != p2.proargtypes[0]);
|
||||
oid | aggname | oid | proname
|
||||
-----+---------+-----+---------
|
||||
a.aggtranstype != p2.proargtypes[0]);
|
||||
aggfnoid | proname | oid | proname
|
||||
----------+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- If transfn is strict then either initval should be non-NULL, or
|
||||
-- basetype should equal transtype so that the first non-null input
|
||||
-- input type should equal transtype so that the first non-null input
|
||||
-- can be assigned as the state value.
|
||||
SELECT p1.oid, p1.aggname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS p1, pg_proc AS p2
|
||||
WHERE p1.aggtransfn = p2.oid AND p2.proisstrict AND
|
||||
p1.agginitval IS NULL AND p1.aggbasetype != p1.aggtranstype;
|
||||
oid | aggname | oid | proname
|
||||
-----+---------+-----+---------
|
||||
SELECT a.aggfnoid::oid, p.proname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS p2
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggtransfn = p2.oid AND p2.proisstrict AND
|
||||
a.agginitval IS NULL AND p.proargtypes[0] != a.aggtranstype;
|
||||
aggfnoid | proname | oid | proname
|
||||
----------+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- **************** pg_opclass ****************
|
||||
@@ -574,6 +616,17 @@ WHERE p1.amopopr = p2.oid AND
|
||||
-----------+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Check that all operators linked to by opclass entries have selectivity
|
||||
-- estimators. This is not absolutely required, but it seems a reasonable
|
||||
-- thing to insist on for all standard datatypes.
|
||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
|
||||
FROM pg_amop AS p1, pg_operator AS p2
|
||||
WHERE p1.amopopr = p2.oid AND
|
||||
(p2.oprrest = 0 OR p2.oprjoin = 0);
|
||||
amopclaid | amopopr | oid | oprname
|
||||
-----------+---------+-----+---------
|
||||
(0 rows)
|
||||
|
||||
-- Check that operator input types match the opclass
|
||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||
FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
|
||||
|
||||
@@ -1024,7 +1024,7 @@ SELECT * FROM shoe_ready WHERE total_avail >= 2;
|
||||
NEW.sl_name,
|
||||
NEW.sl_avail,
|
||||
'Al Bundy',
|
||||
'epoch'::text
|
||||
'epoch'
|
||||
);
|
||||
UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';
|
||||
SELECT * FROM shoelace_log;
|
||||
@@ -1308,8 +1308,8 @@ SELECT viewname, definition FROM pg_views ORDER BY viewname;
|
||||
|
||||
SELECT tablename, rulename, definition FROM pg_rules
|
||||
ORDER BY tablename, rulename;
|
||||
tablename | rulename | definition
|
||||
---------------+-----------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
tablename | rulename | definition
|
||||
---------------+-----------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
rtest_emp | rtest_emp_del | CREATE RULE rtest_emp_del AS ON DELETE TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (old.ename, "current_user"(), 'fired '::bpchar, '$0.00'::money, old.salary);
|
||||
rtest_emp | rtest_emp_ins | CREATE RULE rtest_emp_ins AS ON INSERT TO rtest_emp DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'hired '::bpchar, new.salary, '$0.00'::money);
|
||||
rtest_emp | rtest_emp_upd | CREATE RULE rtest_emp_upd AS ON UPDATE TO rtest_emp WHERE (new.salary <> old.salary) DO INSERT INTO rtest_emplog (ename, who, "action", newsal, oldsal) VALUES (new.ename, "current_user"(), 'honored '::bpchar, new.salary, old.salary);
|
||||
@@ -1335,7 +1335,7 @@ SELECT tablename, rulename, definition FROM pg_rules
|
||||
shoelace | shoelace_del | CREATE RULE shoelace_del AS ON DELETE TO shoelace DO INSTEAD DELETE FROM shoelace_data WHERE (shoelace_data.sl_name = old.sl_name);
|
||||
shoelace | shoelace_ins | CREATE RULE shoelace_ins AS ON INSERT TO shoelace DO INSTEAD INSERT INTO shoelace_data (sl_name, sl_avail, sl_color, sl_len, sl_unit) VALUES (new.sl_name, new.sl_avail, new.sl_color, new.sl_len, new.sl_unit);
|
||||
shoelace | shoelace_upd | CREATE RULE shoelace_upd AS ON UPDATE TO shoelace DO INSTEAD UPDATE shoelace_data SET sl_name = new.sl_name, sl_avail = new.sl_avail, sl_color = new.sl_color, sl_len = new.sl_len, sl_unit = new.sl_unit WHERE (shoelace_data.sl_name = old.sl_name);
|
||||
shoelace_data | log_shoelace | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::name, "timestamp"('epoch'::text));
|
||||
shoelace_data | log_shoelace | CREATE RULE log_shoelace AS ON UPDATE TO shoelace_data WHERE (new.sl_avail <> old.sl_avail) DO INSERT INTO shoelace_log (sl_name, sl_avail, log_who, log_when) VALUES (new.sl_name, new.sl_avail, 'Al Bundy'::name, 'Thu Jan 01 00:00:00 1970'::"timestamp");
|
||||
shoelace_ok | shoelace_ok_ins | CREATE RULE shoelace_ok_ins AS ON INSERT TO shoelace_ok DO INSTEAD UPDATE shoelace SET sl_avail = (shoelace.sl_avail + new.ok_quant) WHERE (shoelace.sl_name = new.ok_name);
|
||||
(27 rows)
|
||||
|
||||
|
||||
@@ -234,8 +234,8 @@ DROP TABLE tmp2;
|
||||
-- is run in parallel with foreign_key.sql.
|
||||
|
||||
CREATE TEMP TABLE PKTABLE (ptest1 int PRIMARY KEY);
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 text);
|
||||
-- This next should fail, because text=int does not exist
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 inet);
|
||||
-- This next should fail, because inet=int does not exist
|
||||
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable;
|
||||
-- This should also fail for the same reason, but here we
|
||||
-- give the column name
|
||||
@@ -250,7 +250,7 @@ ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1) references pktable(ptest1);
|
||||
DROP TABLE pktable;
|
||||
DROP TABLE fktable;
|
||||
|
||||
CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 text,
|
||||
CREATE TEMP TABLE PKTABLE (ptest1 int, ptest2 inet,
|
||||
PRIMARY KEY(ptest1, ptest2));
|
||||
-- This should fail, because we just chose really odd types
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 cidr, ftest2 datetime);
|
||||
@@ -262,7 +262,7 @@ ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
|
||||
references pktable(ptest1, ptest2);
|
||||
-- This fails because we mixed up the column ordering
|
||||
DROP TABLE FKTABLE;
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 text);
|
||||
CREATE TEMP TABLE FKTABLE (ftest1 int, ftest2 inet);
|
||||
ALTER TABLE FKTABLE ADD FOREIGN KEY(ftest1, ftest2)
|
||||
references pktable(ptest2, ptest1);
|
||||
-- As does this...
|
||||
|
||||
@@ -431,11 +431,11 @@ DROP TABLE PKTABLE;
|
||||
--
|
||||
-- Basic one column, two table setup
|
||||
CREATE TABLE PKTABLE (ptest1 int PRIMARY KEY);
|
||||
-- This next should fail, because text=int does not exist
|
||||
CREATE TABLE FKTABLE (ftest1 text REFERENCES pktable);
|
||||
-- This next should fail, because inet=int does not exist
|
||||
CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable);
|
||||
-- This should also fail for the same reason, but here we
|
||||
-- give the column name
|
||||
CREATE TABLE FKTABLE (ftest1 text REFERENCES pktable(ptest1));
|
||||
CREATE TABLE FKTABLE (ftest1 inet REFERENCES pktable(ptest1));
|
||||
-- This should succeed, even though they are different types
|
||||
-- because varchar=int does exist
|
||||
CREATE TABLE FKTABLE (ftest1 varchar REFERENCES pktable);
|
||||
@@ -446,42 +446,42 @@ DROP TABLE FKTABLE;
|
||||
DROP TABLE PKTABLE;
|
||||
|
||||
-- Two columns, two tables
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, PRIMARY KEY(ptest1, ptest2));
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, PRIMARY KEY(ptest1, ptest2));
|
||||
-- This should fail, because we just chose really odd types
|
||||
CREATE TABLE FKTABLE (ftest1 cidr, ftest2 datetime, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable);
|
||||
-- Again, so should this...
|
||||
CREATE TABLE FKTABLE (ftest1 cidr, ftest2 datetime, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
|
||||
-- This fails because we mixed up the column ordering
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable);
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable);
|
||||
-- As does this...
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest1, ptest2));
|
||||
-- And again..
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest2, ptest1));
|
||||
-- This works...
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest2, ftest1) REFERENCES pktable(ptest2, ptest1));
|
||||
DROP TABLE FKTABLE;
|
||||
-- As does this
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 text, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
|
||||
CREATE TABLE FKTABLE (ftest1 int, ftest2 inet, FOREIGN KEY(ftest1, ftest2) REFERENCES pktable(ptest1, ptest2));
|
||||
DROP TABLE FKTABLE;
|
||||
DROP TABLE PKTABLE;
|
||||
|
||||
-- Two columns, same table
|
||||
-- Make sure this still works...
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
ptest4) REFERENCES pktable(ptest1, ptest2));
|
||||
DROP TABLE PKTABLE;
|
||||
-- And this,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
ptest4) REFERENCES pktable);
|
||||
DROP TABLE PKTABLE;
|
||||
-- This shouldn't (mixed up columns)
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest3,
|
||||
ptest4) REFERENCES pktable(ptest2, ptest1));
|
||||
-- Nor should this... (same reason, we have 4,3 referencing 1,2 which mismatches types
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
ptest3) REFERENCES pktable(ptest1, ptest2));
|
||||
-- Not this one either... Same as the last one except we didn't defined the columns being referenced.
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 text, ptest3 int, ptest4 text, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
CREATE TABLE PKTABLE (ptest1 int, ptest2 inet, ptest3 int, ptest4 inet, PRIMARY KEY(ptest1, ptest2), FOREIGN KEY(ptest4,
|
||||
ptest3) REFERENCES pktable);
|
||||
|
||||
--
|
||||
@@ -557,26 +557,26 @@ drop table pktable_base;
|
||||
|
||||
-- 2 columns (2 tables), mismatched types
|
||||
create table pktable_base(base1 int not null);
|
||||
create table pktable(ptest1 text, primary key(base1, ptest1)) inherits (pktable_base);
|
||||
create table pktable(ptest1 inet, primary key(base1, ptest1)) inherits (pktable_base);
|
||||
-- just generally bad types (with and without column references on the referenced table)
|
||||
create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable);
|
||||
create table fktable(ftest1 cidr, ftest2 int[], foreign key (ftest1, ftest2) references pktable(base1, ptest1));
|
||||
-- let's mix up which columns reference which
|
||||
create table fktable(ftest1 int, ftest2 text, foreign key(ftest2, ftest1) references pktable);
|
||||
create table fktable(ftest1 int, ftest2 text, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
|
||||
create table fktable(ftest1 int, ftest2 text, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
|
||||
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable);
|
||||
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest2, ftest1) references pktable(base1, ptest1));
|
||||
create table fktable(ftest1 int, ftest2 inet, foreign key(ftest1, ftest2) references pktable(ptest1, base1));
|
||||
drop table pktable;
|
||||
drop table pktable_base;
|
||||
|
||||
-- 2 columns (1 table), mismatched types
|
||||
create table pktable_base(base1 int not null, base2 int);
|
||||
create table pktable(ptest1 text, ptest2 text[], primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet[], primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
pktable(base1, ptest1)) inherits (pktable_base);
|
||||
create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(base2, ptest2) references
|
||||
pktable(ptest1, base1)) inherits (pktable_base);
|
||||
create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
pktable(base1, ptest1)) inherits (pktable_base);
|
||||
create table pktable(ptest1 text, ptest2 text, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
create table pktable(ptest1 inet, ptest2 inet, primary key(base1, ptest1), foreign key(ptest2, base2) references
|
||||
pktable(base1, ptest1)) inherits (pktable_base);
|
||||
drop table pktable;
|
||||
drop table pktable_base;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
--
|
||||
-- This is created by pgsql/contrib/findoidjoins/make_oidjoin_check
|
||||
--
|
||||
SELECT ctid, pg_aggregate.aggfnoid
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggfnoid != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_proc AS t1 WHERE t1.oid = pg_aggregate.aggfnoid);
|
||||
SELECT ctid, pg_aggregate.aggtransfn
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggtransfn != 0 AND
|
||||
@@ -9,18 +13,10 @@ SELECT ctid, pg_aggregate.aggfinalfn
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggfinalfn != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_proc AS t1 WHERE t1.oid = pg_aggregate.aggfinalfn);
|
||||
SELECT ctid, pg_aggregate.aggbasetype
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggbasetype != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_type AS t1 WHERE t1.oid = pg_aggregate.aggbasetype);
|
||||
SELECT ctid, pg_aggregate.aggtranstype
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggtranstype != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_type AS t1 WHERE t1.oid = pg_aggregate.aggtranstype);
|
||||
SELECT ctid, pg_aggregate.aggfinaltype
|
||||
FROM pg_aggregate
|
||||
WHERE pg_aggregate.aggfinaltype != 0 AND
|
||||
NOT EXISTS(SELECT * FROM pg_type AS t1 WHERE t1.oid = pg_aggregate.aggfinaltype);
|
||||
SELECT ctid, pg_am.amgettuple
|
||||
FROM pg_am
|
||||
WHERE pg_am.amgettuple != 0 AND
|
||||
|
||||
@@ -46,7 +46,7 @@ WHERE p1.oid != p2.oid AND
|
||||
p1.pronargs = p2.pronargs AND
|
||||
p1.proargtypes = p2.proargtypes;
|
||||
|
||||
-- Considering only built-in procs (prolang = 11/12), look for multiple uses
|
||||
-- Considering only built-in procs (prolang = 12), look for multiple uses
|
||||
-- of the same internal function (ie, matching prosrc fields). It's OK to
|
||||
-- have several entries with different pronames for the same internal function,
|
||||
-- but conflicts in the number of arguments and other critical items should
|
||||
@@ -56,14 +56,14 @@ SELECT p1.oid, p1.proname, p2.oid, p2.proname
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
(p1.prolang != p2.prolang OR
|
||||
p1.proisinh != p2.proisinh OR
|
||||
p1.proisagg != p2.proisagg OR
|
||||
p1.proistrusted != p2.proistrusted OR
|
||||
p1.proisstrict != p2.proisstrict OR
|
||||
p1.proretset != p2.proretset OR
|
||||
p1.provolatile != p2.provolatile OR
|
||||
p1.pronargs != p2.pronargs OR
|
||||
p1.proretset != p2.proretset);
|
||||
p1.pronargs != p2.pronargs);
|
||||
|
||||
-- Look for uses of different type OIDs in the argument/result type fields
|
||||
-- for different aliases of the same built-in function.
|
||||
@@ -71,79 +71,95 @@ WHERE p1.oid != p2.oid AND
|
||||
-- That's not wrong, necessarily, but we make lists of all the types being
|
||||
-- so treated. Note that the expected output of this part of the test will
|
||||
-- need to be modified whenever new pairs of types are made binary-equivalent!
|
||||
-- Note: ignore aggregate functions here, since they all point to the same
|
||||
-- dummy built-in function.
|
||||
|
||||
SELECT DISTINCT p1.prorettype, p2.prorettype
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.prorettype < p2.prorettype);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[0], p2.proargtypes[0]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[0] < p2.proargtypes[0]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[1], p2.proargtypes[1]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[1] < p2.proargtypes[1]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[2], p2.proargtypes[2]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[2] < p2.proargtypes[2]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[3], p2.proargtypes[3]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[3] < p2.proargtypes[3]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[4], p2.proargtypes[4]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[4] < p2.proargtypes[4]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[5], p2.proargtypes[5]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[5] < p2.proargtypes[5]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[6], p2.proargtypes[6]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[6] < p2.proargtypes[6]);
|
||||
|
||||
SELECT DISTINCT p1.proargtypes[7], p2.proargtypes[7]
|
||||
FROM pg_proc AS p1, pg_proc AS p2
|
||||
WHERE p1.oid != p2.oid AND
|
||||
p1.prosrc = p2.prosrc AND
|
||||
(p1.prolang = 11 OR p1.prolang = 12) AND
|
||||
(p2.prolang = 11 OR p2.prolang = 12) AND
|
||||
p1.prolang = 12 AND p2.prolang = 12 AND
|
||||
NOT p1.proisagg AND NOT p2.proisagg AND
|
||||
(p1.proargtypes[7] < p2.proargtypes[7]);
|
||||
|
||||
-- If a proc is marked as an implicit cast, then it should be something that
|
||||
-- the system might actually use as a cast function: name same as the name
|
||||
-- of its output type, and either one arg that's a different type, or two
|
||||
-- args where the first is the same as the output type and the second is int4.
|
||||
|
||||
SELECT p1.oid, p1.proname
|
||||
FROM pg_proc as p1
|
||||
WHERE p1.proimplicit AND
|
||||
(NOT EXISTS (SELECT 1 FROM pg_type t WHERE t.oid = p1.prorettype AND
|
||||
t.typname = p1.proname) OR
|
||||
NOT ((p1.pronargs = 1 AND p1.proargtypes[0] != prorettype) OR
|
||||
(p1.pronargs = 2 AND p1.proargtypes[0] = prorettype AND
|
||||
p1.proargtypes[1] = 23)));
|
||||
|
||||
-- **************** pg_operator ****************
|
||||
|
||||
-- Look for illegal values in pg_operator fields.
|
||||
@@ -192,6 +208,7 @@ WHERE p1.oprcom = p2.oid AND
|
||||
-- single-operand operators.
|
||||
-- We expect that B will always say that B.oprnegate = A as well; that's not
|
||||
-- inherently essential, but it would be inefficient not to mark it so.
|
||||
-- Also, A and B had better not be the same operator.
|
||||
|
||||
SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcode
|
||||
FROM pg_operator AS p1, pg_operator AS p2
|
||||
@@ -201,7 +218,8 @@ WHERE p1.oprnegate = p2.oid AND
|
||||
p1.oprright != p2.oprright OR
|
||||
p1.oprresult != 16 OR
|
||||
p2.oprresult != 16 OR
|
||||
p1.oid != p2.oprnegate);
|
||||
p1.oid != p2.oprnegate OR
|
||||
p1.oid = p2.oid);
|
||||
|
||||
-- Look for mergejoin operators that don't match their links.
|
||||
-- A mergejoin link leads from an '=' operator to the
|
||||
@@ -378,15 +396,30 @@ WHERE p1.oprjoin = p2.oid AND
|
||||
|
||||
-- Look for illegal values in pg_aggregate fields.
|
||||
|
||||
SELECT p1.oid, p1.aggname
|
||||
SELECT ctid, aggfnoid::oid
|
||||
FROM pg_aggregate as p1
|
||||
WHERE aggtransfn = 0 OR aggtranstype = 0 OR aggfinaltype = 0;
|
||||
WHERE aggfnoid = 0 OR aggtransfn = 0 OR aggtranstype = 0;
|
||||
|
||||
-- Make sure the matching pg_proc entry is sensible, too.
|
||||
|
||||
SELECT a.aggfnoid::oid, p.proname
|
||||
FROM pg_aggregate as a, pg_proc as p
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
(NOT p.proisagg OR p.pronargs != 1 OR p.proretset);
|
||||
|
||||
-- Make sure there are no proisagg pg_proc entries without matches.
|
||||
|
||||
SELECT oid, proname
|
||||
FROM pg_proc as p
|
||||
WHERE p.proisagg AND
|
||||
NOT EXISTS (SELECT 1 FROM pg_aggregate a WHERE a.aggfnoid = p.oid);
|
||||
|
||||
-- If there is no finalfn then the output type must be the transtype.
|
||||
|
||||
SELECT p1.oid, p1.aggname
|
||||
FROM pg_aggregate as p1
|
||||
WHERE p1.aggfinalfn = 0 AND p1.aggfinaltype != p1.aggtranstype;
|
||||
SELECT a.aggfnoid::oid, p.proname
|
||||
FROM pg_aggregate as a, pg_proc as p
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype;
|
||||
|
||||
-- Cross-check transfn against its entry in pg_proc.
|
||||
-- FIXME: what about binary-compatible types?
|
||||
@@ -394,33 +427,36 @@ WHERE p1.aggfinalfn = 0 AND p1.aggfinaltype != p1.aggtranstype;
|
||||
-- implemented using int4larger/int4smaller. Until we have
|
||||
-- some cleaner way of dealing with binary-equivalent types, just leave
|
||||
-- those two tuples in the expected output.
|
||||
SELECT p1.oid, p1.aggname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS p1, pg_proc AS p2
|
||||
WHERE p1.aggtransfn = p2.oid AND
|
||||
SELECT a.aggfnoid::oid, p.proname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS p2
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggtransfn = p2.oid AND
|
||||
(p2.proretset OR
|
||||
p1.aggtranstype != p2.prorettype OR
|
||||
p1.aggtranstype != p2.proargtypes[0] OR
|
||||
NOT ((p2.pronargs = 2 AND p1.aggbasetype = p2.proargtypes[1]) OR
|
||||
(p2.pronargs = 1 AND p1.aggbasetype = 0)));
|
||||
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)));
|
||||
|
||||
-- Cross-check finalfn (if present) against its entry in pg_proc.
|
||||
-- FIXME: what about binary-compatible types?
|
||||
|
||||
SELECT p1.oid, p1.aggname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS p1, pg_proc AS p2
|
||||
WHERE p1.aggfinalfn = p2.oid AND
|
||||
(p2.proretset OR p1.aggfinaltype != p2.prorettype OR
|
||||
SELECT a.aggfnoid::oid, p.proname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS p2
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggfinalfn = p2.oid AND
|
||||
(p2.proretset OR p.prorettype != p2.prorettype OR
|
||||
p2.pronargs != 1 OR
|
||||
p1.aggtranstype != p2.proargtypes[0]);
|
||||
a.aggtranstype != p2.proargtypes[0]);
|
||||
|
||||
-- If transfn is strict then either initval should be non-NULL, or
|
||||
-- basetype should equal transtype so that the first non-null input
|
||||
-- input type should equal transtype so that the first non-null input
|
||||
-- can be assigned as the state value.
|
||||
|
||||
SELECT p1.oid, p1.aggname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS p1, pg_proc AS p2
|
||||
WHERE p1.aggtransfn = p2.oid AND p2.proisstrict AND
|
||||
p1.agginitval IS NULL AND p1.aggbasetype != p1.aggtranstype;
|
||||
SELECT a.aggfnoid::oid, p.proname, p2.oid, p2.proname
|
||||
FROM pg_aggregate AS a, pg_proc AS p, pg_proc AS p2
|
||||
WHERE a.aggfnoid = p.oid AND
|
||||
a.aggtransfn = p2.oid AND p2.proisstrict AND
|
||||
a.agginitval IS NULL AND p.proargtypes[0] != a.aggtranstype;
|
||||
|
||||
-- **************** pg_opclass ****************
|
||||
|
||||
@@ -473,6 +509,15 @@ FROM pg_amop AS p1, pg_operator AS p2
|
||||
WHERE p1.amopopr = p2.oid AND
|
||||
(p2.oprkind != 'b' OR p2.oprresult != 16 OR p2.oprleft != p2.oprright);
|
||||
|
||||
-- Check that all operators linked to by opclass entries have selectivity
|
||||
-- estimators. This is not absolutely required, but it seems a reasonable
|
||||
-- thing to insist on for all standard datatypes.
|
||||
|
||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
|
||||
FROM pg_amop AS p1, pg_operator AS p2
|
||||
WHERE p1.amopopr = p2.oid AND
|
||||
(p2.oprrest = 0 OR p2.oprjoin = 0);
|
||||
|
||||
-- Check that operator input types match the opclass
|
||||
|
||||
SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
|
||||
|
||||
@@ -604,7 +604,7 @@ SELECT * FROM shoe_ready WHERE total_avail >= 2;
|
||||
NEW.sl_name,
|
||||
NEW.sl_avail,
|
||||
'Al Bundy',
|
||||
'epoch'::text
|
||||
'epoch'
|
||||
);
|
||||
|
||||
UPDATE shoelace_data SET sl_avail = 6 WHERE sl_name = 'sl7';
|
||||
|
||||
Reference in New Issue
Block a user