opr_sanity.sql

来自「PostgreSQL7.4.6 for Linux」· SQL 代码 · 共 693 行 · 第 1/2 页

SQL
693
字号
---- OPR_SANITY-- Sanity checks for common errors in making operator/procedure system tables:-- pg_operator, pg_proc, pg_cast, pg_aggregate, pg_am, pg_amop, pg_amproc, pg_opclass.---- None of the SELECTs here should ever find any matching entries,-- so the expected output is easy to maintain ;-).-- A test failure indicates someone messed up an entry in the system tables.---- NB: we assume the oidjoins test will have caught any dangling links,-- that is OID or REGPROC fields that are not zero and do not match some-- row in the linked-to table.  However, if we want to enforce that a link-- field can't be 0, we have to check it here.---- NB: run this test earlier than the create_operator test, because-- that test creates some bogus operators...-- Helper functions to deal with cases where binary-coercible matches are-- allowed.-- This should match IsBinaryCoercible() in parse_coerce.c.create function binary_coercible(oid, oid) returns bool as'SELECT ($1 = $2) OR EXISTS(select 1 from pg_cast where        castsource = $1 and casttarget = $2 and        castfunc = 0 and castcontext = ''i'')'language sql;-- This one ignores castcontext, so it considers only physical equivalence-- and not whether the coercion can be invoked implicitly.create function physically_coercible(oid, oid) returns bool as'SELECT ($1 = $2) OR EXISTS(select 1 from pg_cast where        castsource = $1 and casttarget = $2 and        castfunc = 0)'language sql;-- **************** pg_proc ****************-- Look for illegal values in pg_proc fields.-- 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.pronameFROM pg_proc as p1WHERE 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-- pg_proc_proname_narg_type_index, but I'll leave it in anyway.)SELECT p1.oid, p1.proname, p2.oid, p2.pronameFROM pg_proc AS p1, pg_proc AS p2WHERE p1.oid != p2.oid AND    p1.proname = p2.proname AND    p1.pronargs = p2.pronargs AND    p1.proargtypes = p2.proargtypes;-- 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-- be complained of.SELECT p1.oid, p1.proname, p2.oid, p2.pronameFROM pg_proc AS p1, pg_proc AS p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc AND    p1.prolang = 12 AND p2.prolang = 12 AND    (p1.prolang != p2.prolang OR     p1.proisagg != p2.proisagg OR     p1.prosecdef != p2.prosecdef OR     p1.proisstrict != p2.proisstrict OR     p1.proretset != p2.proretset OR     p1.provolatile != p2.provolatile OR     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.-- This indicates that the types are being presumed to be binary-equivalent,-- or that the built-in function is prepared to deal with different types.-- 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,-- or when new polymorphic built-in functions are added!-- Note: ignore aggregate functions here, since they all point to the same-- dummy built-in function.SELECT DISTINCT p1.prorettype, p2.prorettypeFROM pg_proc AS p1, pg_proc AS p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc 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 p2WHERE p1.oid != p2.oid AND    p1.prosrc = p2.prosrc AND    p1.prolang = 12 AND p2.prolang = 12 AND    NOT p1.proisagg AND NOT p2.proisagg AND    (p1.proargtypes[7] < p2.proargtypes[7]);-- Look for functions that return type "internal" and do not have any-- "internal" argument.  Such a function would be a security hole since-- it might be used to call an internal function from an SQL command.-- As of 7.3 this query should find only internal_in.SELECT p1.oid, p1.pronameFROM pg_proc as p1WHERE p1.prorettype = 'internal'::regtype AND NOT    ('(' || oidvectortypes(p1.proargtypes) || ')') ~ '[^a-z0-9_]internal[^a-z0-9_]';-- **************** pg_cast ****************-- Look for casts from and to the same type.  This is not harmful, but-- useless.  Also catch bogus values in pg_cast columns (other than-- cases detected by oidjoins test).SELECT *FROM pg_cast cWHERE castsource = casttarget OR castsource = 0 OR casttarget = 0    OR castcontext NOT IN ('e', 'a', 'i');-- Look for cast functions that don't have the right signature.  The-- argument and result types in pg_proc must be the same as, or binary-- compatible with, what it says in pg_cast.SELECT c.*FROM pg_cast c, pg_proc pWHERE c.castfunc = p.oid AND    (p.pronargs <> 1     OR NOT binary_coercible(c.castsource, p.proargtypes[0])     OR NOT binary_coercible(p.prorettype, c.casttarget));-- Look for binary compatible casts that do not have the reverse-- direction registered as well, or where the reverse direction is not-- also binary compatible.  This is legal, but usually not intended.-- As of 7.4, this finds the casts from text and varchar to bpchar, because-- those are binary-compatible while the reverse way goes through rtrim().SELECT *FROM pg_cast cWHERE c.castfunc = 0 AND    NOT EXISTS (SELECT 1 FROM pg_cast k                WHERE k.castfunc = 0 AND                    k.castsource = c.casttarget AND                    k.casttarget = c.castsource);-- **************** pg_operator ****************-- Look for illegal values in pg_operator fields.SELECT p1.oid, p1.oprnameFROM pg_operator as p1WHERE (p1.oprkind != 'b' AND p1.oprkind != 'l' AND p1.oprkind != 'r') OR    p1.oprresult = 0 OR p1.oprcode = 0;-- Look for missing or unwanted operand typesSELECT p1.oid, p1.oprnameFROM pg_operator as p1WHERE (p1.oprleft = 0 and p1.oprkind != 'l') OR    (p1.oprleft != 0 and p1.oprkind = 'l') OR    (p1.oprright = 0 and p1.oprkind != 'r') OR    (p1.oprright != 0 and p1.oprkind = 'r');-- Look for conflicting operator definitions (same names and input datatypes).SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oid != p2.oid AND    p1.oprname = p2.oprname AND    p1.oprkind = p2.oprkind AND    p1.oprleft = p2.oprleft AND    p1.oprright = p2.oprright;-- 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);-- Look for mergejoin operators that don't match their links.-- An lsortop/rsortop link leads from an '=' operator to the-- sort operator ('<' operator) that's appropriate for-- its left-side or right-side data type.-- An ltcmpop/gtcmpop link leads from an '=' operator to the-- '<' or '>' operator of the same input datatypes.-- (If the '=' operator has identical L and R input datatypes,-- then lsortop, rsortop, and ltcmpop are all the same operator.)SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprlsortop = p2.oid AND    (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR     p1.oprkind != 'b' OR p2.oprkind != 'b' OR     p1.oprleft != p2.oprleft OR     p1.oprleft != p2.oprright OR     p1.oprresult != 'bool'::regtype OR     p2.oprresult != 'bool'::regtype);SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprrsortop = p2.oid AND    (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR     p1.oprkind != 'b' OR p2.oprkind != 'b' OR     p1.oprright != p2.oprleft OR     p1.oprright != p2.oprright OR     p1.oprresult != 'bool'::regtype OR     p2.oprresult != 'bool'::regtype);SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprltcmpop = p2.oid AND    (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('<', '~<~') OR     p1.oprkind != 'b' OR p2.oprkind != 'b' OR     p1.oprleft != p2.oprleft OR     p1.oprright != p2.oprright OR     p1.oprresult != 'bool'::regtype OR     p2.oprresult != 'bool'::regtype);SELECT p1.oid, p1.oprcode, p2.oid, p2.oprcodeFROM pg_operator AS p1, pg_operator AS p2WHERE p1.oprgtcmpop = p2.oid AND    (p1.oprname NOT IN ('=', '~=~') OR p2.oprname NOT IN ('>', '~>~') OR     p1.oprkind != 'b' OR p2.oprkind != 'b' OR     p1.oprleft != p2.oprleft OR     p1.oprright != p2.oprright OR     p1.oprresult != 'bool'::regtype OR     p2.oprresult != 'bool'::regtype);-- Make sure all four links are specified if any are.SELECT p1.oid, p1.oprcodeFROM pg_operator AS p1WHERE NOT ((oprlsortop = 0 AND oprrsortop = 0 AND            oprltcmpop = 0 AND oprgtcmpop = 0) OR           (oprlsortop != 0 AND oprrsortop != 0 AND            oprltcmpop != 0 AND oprgtcmpop != 0));-- A mergejoinable = operator must have a commutator (usually itself).SELECT p1.oid, p1.oprname FROM pg_operator AS p1WHERE p1.oprlsortop != 0 AND      p1.oprcom = 0;-- Mergejoinable operators across datatypes must come in closed sets, that

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?