opr_sanity.sql
来自「PostgreSQL7.4.6 for Linux」· SQL 代码 · 共 693 行 · 第 1/2 页
SQL
693 行
-- is if you provide int2 = int4 and int4 = int8 then you must also provide-- int2 = int8 (and commutators of all these). This is necessary because-- the planner tries to deduce additional qual clauses from transitivity-- of mergejoinable operators. If there are clauses int2var = int4var and-- int4var = int8var, the planner will deduce int2var = int8var ... and it-- had better have a way to represent it.SELECT p1.oid, p2.oid FROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprlsortop != p1.oprrsortop AND p1.oprrsortop = p2.oprlsortop AND p2.oprlsortop != p2.oprrsortop AND NOT EXISTS (SELECT 1 FROM pg_operator p3 WHERE p3.oprlsortop = p1.oprlsortop AND p3.oprrsortop = p2.oprrsortop);-- Hashing only works on simple equality operators "type = sametype",-- since the hash itself depends on the bitwise representation of the type.-- Check that allegedly hashable operators look like they might be "=".SELECT p1.oid, p1.oprnameFROM pg_operator AS p1WHERE p1.oprcanhash AND NOT (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprleft = p1.oprright AND p1.oprname IN ('=', '~=~') AND p1.oprcom = p1.oid);-- In 6.5 we accepted hashable array equality operators when the array element-- type is hashable. However, what we actually need to make hashjoin work on-- an array is a hashable element type *and* no padding between elements in-- the array storage (or, perhaps, guaranteed-zero padding). Currently,-- since the padding code in arrayfuncs.c is pretty bogus, it seems safest-- to just forbid hashjoin on array equality ops.-- This should be reconsidered someday.-- -- Look for array equality operators that are hashable when the underlying-- -- type is not, or vice versa. This is presumably bogus.-- -- SELECT p1.oid, p1.oprcanhash, p2.oid, p2.oprcanhash, t1.typname, t2.typname-- FROM pg_operator AS p1, pg_operator AS p2, pg_type AS t1, pg_type AS t2-- WHERE p1.oprname = '=' AND p1.oprleft = p1.oprright AND -- p2.oprname = '=' AND p2.oprleft = p2.oprright AND-- p1.oprleft = t1.oid AND p2.oprleft = t2.oid AND t1.typelem = t2.oid AND-- p1.oprcanhash != p2.oprcanhash;-- Substitute check: forbid hashable array ops, period.SELECT p1.oid, p1.oprnameFROM pg_operator AS p1, pg_proc AS p2WHERE p1.oprcanhash AND p1.oprcode = p2.oid AND p2.proname = 'array_eq';-- Hashable operators should appear as members of hash index opclasses.SELECT p1.oid, p1.oprnameFROM pg_operator AS p1WHERE p1.oprcanhash AND NOT EXISTS (SELECT 1 FROM pg_opclass op JOIN pg_amop p ON op.oid = amopclaid WHERE opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') AND amopopr = p1.oid);-- Check that each operator defined in pg_operator matches its oprcode entry-- in pg_proc. Easiest to do this separately for each oprkind.SELECT p1.oid, p1.oprname, p2.oid, p2.pronameFROM pg_operator AS p1, pg_proc AS p2WHERE p1.oprcode = p2.oid AND p1.oprkind = 'b' AND (p2.pronargs != 2 OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0]) OR NOT binary_coercible(p1.oprright, p2.proargtypes[1]));SELECT p1.oid, p1.oprname, p2.oid, p2.pronameFROM pg_operator AS p1, pg_proc AS p2WHERE p1.oprcode = p2.oid AND p1.oprkind = 'l' AND (p2.pronargs != 1 OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.oprright, p2.proargtypes[0]) OR p1.oprleft != 0);SELECT p1.oid, p1.oprname, p2.oid, p2.pronameFROM pg_operator AS p1, pg_proc AS p2WHERE p1.oprcode = p2.oid AND p1.oprkind = 'r' AND (p2.pronargs != 1 OR NOT binary_coercible(p2.prorettype, p1.oprresult) OR NOT binary_coercible(p1.oprleft, p2.proargtypes[0]) OR p1.oprright != 0);-- If the operator is mergejoinable or hashjoinable, its underlying function-- should not be volatile.SELECT p1.oid, p1.oprname, p2.oid, p2.pronameFROM pg_operator AS p1, pg_proc AS p2WHERE p1.oprcode = p2.oid AND (p1.oprlsortop != 0 OR p1.oprcanhash) AND p2.provolatile = 'v';-- 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(internal, oid, internal, int4)SELECT p1.oid, p1.oprname, p2.oid, p2.pronameFROM pg_operator AS p1, pg_proc AS p2WHERE 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] != '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(internal, oid, internal, int2)SELECT p1.oid, p1.oprname, p2.oid, p2.pronameFROM pg_operator AS p1, pg_proc AS p2WHERE p1.oprjoin = p2.oid AND (p1.oprkind != 'b' OR p1.oprresult != 'bool'::regtype OR p2.prorettype != 'float8'::regtype OR p2.proretset OR p2.pronargs != 4 OR p2.proargtypes[0] != 'internal'::regtype OR p2.proargtypes[1] != 'oid'::regtype OR p2.proargtypes[2] != 'internal'::regtype OR p2.proargtypes[3] != 'int2'::regtype);-- **************** pg_aggregate ****************-- Look for illegal values in pg_aggregate fields.SELECT ctid, aggfnoid::oidFROM pg_aggregate as p1WHERE aggfnoid = 0 OR aggtransfn = 0 OR aggtranstype = 0;-- Make sure the matching pg_proc entry is sensible, too.SELECT a.aggfnoid::oid, p.pronameFROM pg_aggregate as a, pg_proc as pWHERE 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, pronameFROM pg_proc as pWHERE 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 a.aggfnoid::oid, p.pronameFROM pg_aggregate as a, pg_proc as pWHERE a.aggfnoid = p.oid AND a.aggfinalfn = 0 AND p.prorettype != a.aggtranstype;-- Cross-check transfn against its entry in pg_proc.-- NOTE: use physically_coercible here, not binary_coercible, because-- max and min on abstime are implemented using int4larger/int4smaller.SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.pronameFROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptrWHERE a.aggfnoid = p.oid AND a.aggtransfn = ptr.oid AND (ptr.proretset OR NOT physically_coercible(ptr.prorettype, a.aggtranstype) OR NOT physically_coercible(a.aggtranstype, ptr.proargtypes[0]) OR NOT ((ptr.pronargs = 2 AND physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (ptr.pronargs = 1 AND p.proargtypes[0] = '"any"'::regtype)));-- Cross-check finalfn (if present) against its entry in pg_proc.SELECT a.aggfnoid::oid, p.proname, pfn.oid, pfn.pronameFROM pg_aggregate AS a, pg_proc AS p, pg_proc AS pfnWHERE a.aggfnoid = p.oid AND a.aggfinalfn = pfn.oid AND (pfn.proretset OR NOT binary_coercible(pfn.prorettype, p.prorettype) OR pfn.pronargs != 1 OR NOT binary_coercible(a.aggtranstype, pfn.proargtypes[0]));-- If transfn is strict then either initval should be non-NULL, or-- input type should match transtype so that the first non-null input-- can be assigned as the state value.SELECT a.aggfnoid::oid, p.proname, ptr.oid, ptr.pronameFROM pg_aggregate AS a, pg_proc AS p, pg_proc AS ptrWHERE a.aggfnoid = p.oid AND a.aggtransfn = ptr.oid AND ptr.proisstrict AND a.agginitval IS NULL AND NOT binary_coercible(p.proargtypes[0], a.aggtranstype);-- **************** pg_opclass ****************-- Look for illegal values in pg_opclass fieldsSELECT p1.oidFROM pg_opclass as p1WHERE p1.opcamid = 0 OR p1.opcintype = 0;-- There should not be multiple entries in pg_opclass with opcdefault true-- and the same opcamid/opcintype combination.SELECT p1.oid, p2.oidFROM pg_opclass AS p1, pg_opclass AS p2WHERE p1.oid != p2.oid AND p1.opcamid = p2.opcamid AND p1.opcintype = p2.opcintype AND p1.opcdefault AND p2.opcdefault;-- **************** pg_amop ****************-- Look for illegal values in pg_amop fieldsSELECT p1.amopclaid, p1.amopstrategyFROM pg_amop as p1WHERE p1.amopclaid = 0 OR p1.amopstrategy <= 0 OR p1.amopopr = 0;-- Cross-check amopstrategy index against parent AMSELECT p1.amopclaid, p1.amopopr, p2.oid, p2.amnameFROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND p1.amopstrategy > p2.amstrategies;-- Detect missing pg_amop entries: should have as many strategy functions-- as AM expects for each opclass for the AMSELECT p1.oid, p1.amname, p2.oid, p2.opcnameFROM pg_am AS p1, pg_opclass AS p2WHERE p2.opcamid = p1.oid AND p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3 WHERE p3.amopclaid = p2.oid);-- Check that amopopr points at a reasonable-looking operator, ie a binary-- operator yielding boolean.-- NOTE: for 7.1, add restriction that operator inputs are of same type.-- We used to have opclasses like "int24_ops" but these were broken.SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprnameFROM pg_amop AS p1, pg_operator AS p2WHERE p1.amopopr = p2.oid AND (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype 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.oprnameFROM pg_amop AS p1, pg_operator AS p2WHERE p1.amopopr = p2.oid AND (p2.oprrest = 0 OR p2.oprjoin = 0);-- Check that operator input types match the opclassSELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcnameFROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND (NOT binary_coercible(p3.opcintype, p2.oprleft) OR p2.oprleft != p2.oprright);-- **************** pg_amproc ****************-- Look for illegal values in pg_amproc fieldsSELECT p1.amopclaid, p1.amprocnumFROM pg_amproc as p1WHERE p1.amopclaid = 0 OR p1.amprocnum <= 0 OR p1.amproc = 0;-- Cross-check amprocnum index against parent AMSELECT p1.amopclaid, p1.amprocnum, p2.oid, p2.amnameFROM pg_amproc AS p1, pg_am AS p2, pg_opclass AS p3WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND p1.amprocnum > p2.amsupport;-- Detect missing pg_amproc entries: should have as many support functions-- as AM expects for each opclass for the AMSELECT p1.oid, p1.amname, p2.oid, p2.opcnameFROM pg_am AS p1, pg_opclass AS p2WHERE p2.opcamid = p1.oid AND p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3 WHERE p3.amopclaid = p2.oid);-- Unfortunately, we can't check the amproc link very well because the-- signature of the function may be different for different support routines-- or different base data types.-- We can check that all the referenced instances of the same support-- routine number take the same number of parameters, but that's about it-- for a general check...SELECT p1.amopclaid, p1.amprocnum, p2.oid, p2.proname, p3.opcname, p4.amopclaid, p4.amprocnum, p5.oid, p5.proname, p6.opcnameFROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3, pg_amproc AS p4, pg_proc AS p5, pg_opclass AS p6WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND p3.opcamid = p6.opcamid AND p1.amprocnum = p4.amprocnum AND p1.amproc = p2.oid AND p4.amproc = p5.oid AND (p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs);-- For btree, though, we can do better since we know the support routines-- must be of the form cmp(input, input) returns int4.SELECT p1.amopclaid, p1.amprocnum, p2.oid, p2.proname, p3.opcnameFROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree') AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND (opckeytype != 0 OR amprocnum != 1 OR proretset OR prorettype != 23 OR pronargs != 2 OR NOT binary_coercible(opcintype, proargtypes[0]) OR proargtypes[0] != proargtypes[1]);-- For hash we can also do a little better: the support routines must be-- of the form hash(something) returns int4. Ideally we'd check that the-- opcintype is binary-coercible to the function's input, but there are-- enough cases where that fails that I'll just leave out the check for now.SELECT p1.amopclaid, p1.amprocnum, p2.oid, p2.proname, p3.opcnameFROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'hash') AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND (opckeytype != 0 OR amprocnum != 1 OR proretset OR prorettype != 23 OR pronargs != 1-- OR NOT physically_coercible(opcintype, proargtypes[0]));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?