opr_sanity.sql
来自「postgresql8.3.4源码,开源数据库」· SQL 代码 · 共 838 行 · 第 1/3 页
SQL
838 行
-- Look for commutative operators that don't commute.-- DEFINITIONAL NOTE: If A.oprcom = B, then x A y has the same result as y B x.-- We expect that B will always say that B.oprcom = A as well; that's not-- inherently essential, but it would be inefficient not to mark it so.SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprcom = p2.oid AND (p1.oprkind != 'b' OR p1.oprleft != p2.oprright OR p1.oprright != p2.oprleft OR p1.oprresult != p2.oprresult OR p1.oid != p2.oprcom);-- Look for negatory operators that don't agree.-- DEFINITIONAL NOTE: If A.oprnegate = B, then both A and B must yield-- boolean results, and (x A y) == ! (x B y), or the equivalent for-- 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.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprnegate = p2.oid AND (p1.oprkind != p2.oprkind OR p1.oprleft != p2.oprleft OR p1.oprright != p2.oprright OR p1.oprresult != 'bool'::regtype OR p2.oprresult != 'bool'::regtype OR p1.oid != p2.oprnegate OR p1.oid = p2.oid);-- A mergejoinable or hashjoinable operator must be binary, must return-- boolean, and must have a commutator (itself, unless it's a cross-type-- operator).SELECT p1.oid, p1.oprname FROM pg_operator AS p1WHERE (p1.oprcanmerge OR p1.oprcanhash) AND NOT (p1.oprkind = 'b' AND p1.oprresult = 'bool'::regtype AND p1.oprcom != 0);-- What's more, the commutator had better be mergejoinable/hashjoinable too.SELECT p1.oid, p1.oprname, p2.oid, p2.oprnameFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprcom = p2.oid AND (p1.oprcanmerge != p2.oprcanmerge OR p1.oprcanhash != p2.oprcanhash);-- Mergejoinable operators should appear as equality members of btree index-- opfamilies.SELECT p1.oid, p1.oprnameFROM pg_operator AS p1WHERE p1.oprcanmerge AND NOT EXISTS (SELECT 1 FROM pg_amop WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND amopopr = p1.oid AND amopstrategy = 3);-- And the converse.SELECT p1.oid, p1.oprname, p.amopfamilyFROM pg_operator AS p1, pg_amop pWHERE amopopr = p1.oid AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND amopstrategy = 3 AND NOT p1.oprcanmerge;-- Hashable operators should appear as members of hash index opfamilies.SELECT p1.oid, p1.oprnameFROM pg_operator AS p1WHERE p1.oprcanhash AND NOT EXISTS (SELECT 1 FROM pg_amop WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND amopopr = p1.oid AND amopstrategy = 1);-- And the converse.SELECT p1.oid, p1.oprname, p.amopfamilyFROM pg_operator AS p1, pg_amop pWHERE amopopr = p1.oid AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'hash') AND NOT p1.oprcanhash;-- 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.oprcanmerge 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.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 (ptr.pronargs = p.pronargs + 1) OR NOT physically_coercible(ptr.prorettype, a.aggtranstype) OR NOT physically_coercible(a.aggtranstype, ptr.proargtypes[0]) OR (p.pronargs > 0 AND NOT physically_coercible(p.proargtypes[0], ptr.proargtypes[1])) OR (p.pronargs > 1 AND NOT physically_coercible(p.proargtypes[1], ptr.proargtypes[2])) OR (p.pronargs > 2 AND NOT physically_coercible(p.proargtypes[2], ptr.proargtypes[3])) -- we could carry the check further, but that's enough for now );-- 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);-- Cross-check aggsortop (if present) against pg_operator.-- We expect to find only "<" for "min" and ">" for "max".SELECT DISTINCT proname, oprnameFROM pg_operator AS o, pg_aggregate AS a, pg_proc AS pWHERE a.aggfnoid = p.oid AND a.aggsortop = o.oidORDER BY 1;-- Check datatypes matchSELECT a.aggfnoid::oid, o.oidFROM pg_operator AS o, pg_aggregate AS a, pg_proc AS pWHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND (oprkind != 'b' OR oprresult != 'boolean'::regtype OR oprleft != p.proargtypes[0] OR oprright != p.proargtypes[0]);-- Check operator is a suitable btree opfamily memberSELECT a.aggfnoid::oid, o.oidFROM pg_operator AS o, pg_aggregate AS a, pg_proc AS pWHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND NOT EXISTS(SELECT 1 FROM pg_amop WHERE amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree') AND amopopr = o.oid AND amoplefttype = o.oprleft AND amoprighttype = o.oprright);-- Check correspondence of btree strategies and namesSELECT DISTINCT proname, oprname, amopstrategyFROM pg_operator AS o, pg_aggregate AS a, pg_proc AS p, pg_amop as aoWHERE a.aggfnoid = p.oid AND a.aggsortop = o.oid AND amopopr = o.oid AND amopmethod = (SELECT oid FROM pg_am WHERE amname = 'btree')ORDER BY 1, 2;-- **************** pg_opfamily ****************-- Look for illegal values in pg_opfamily fieldsSELECT p1.oidFROM pg_opfamily as p1WHERE p1.opfmethod = 0 OR p1.opfnamespace = 0;-- **************** pg_opclass ****************-- Look for illegal values in pg_opclass fieldsSELECT p1.oidFROM pg_opclass AS p1WHERE p1.opcmethod = 0 OR p1.opcnamespace = 0 OR p1.opcfamily = 0 OR p1.opcintype = 0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?