1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
|
-- Use DO to ignore failures when the shared library doesn't exist, because it
-- only existed for 1.3.1, and if upgrades are running from a later release it
-- won't be there.
DO $$
BEGIN
CREATE FUNCTION parse_type(type text, OUT typid oid, OUT typmod int4)
RETURNS RECORD
AS 'pgtap'
LANGUAGE C STABLE STRICT;
EXCEPTION
WHEN undefined_file THEN
RAISE NOTICE 'No pgtap shared library; skipping C parse_type()';
END;
$$;
CREATE OR REPLACE FUNCTION format_type_string ( TEXT )
RETURNS TEXT AS $$
BEGIN RETURN format_type(p.typid, p.typmod) from parse_type($1) p;
EXCEPTION WHEN OTHERS THEN RETURN NULL;
END;
$$ LANGUAGE PLPGSQL STABLE;
-- col_type_is( schema, table, column, schema, type, description )
CREATE OR REPLACE FUNCTION col_type_is ( NAME, NAME, NAME, NAME, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
have_type TEXT := _get_col_ns_type($1, $2, $3);
want_type TEXT;
BEGIN
IF have_type IS NULL THEN
RETURN fail( $6 ) || E'\n' || diag (
' Column ' || COALESCE(quote_ident($1) || '.', '')
|| quote_ident($2) || '.' || quote_ident($3) || ' does not exist'
);
END IF;
IF quote_ident($4) = ANY(current_schemas(true)) THEN
want_type := quote_ident($4) || '.' || format_type_string($5);
ELSE
want_type := format_type_string(quote_ident($4) || '.' || $5);
END IF;
IF want_type IS NULL THEN
RETURN fail( $6 ) || E'\n' || diag (
' Type ' || quote_ident($4) || '.' || $5 || ' does not exist'
);
END IF;
IF have_type = want_type THEN
-- We're good to go.
RETURN ok( true, $6 );
END IF;
-- Wrong data type. tell 'em what we really got.
RETURN ok( false, $6 ) || E'\n' || diag(
' have: ' || have_type ||
E'\n want: ' || want_type
);
END;
$$ LANGUAGE plpgsql;
-- col_type_is( schema, table, column, schema, type )
CREATE OR REPLACE FUNCTION col_type_is ( NAME, NAME, NAME, NAME, TEXT )
RETURNS TEXT AS $$
SELECT col_type_is( $1, $2, $3, $4, $5, 'Column ' || quote_ident($1) || '.' || quote_ident($2)
|| '.' || quote_ident($3) || ' should be type ' || quote_ident($4) || '.' || $5);
$$ LANGUAGE SQL;
-- col_type_is( schema, table, column, type, description )
CREATE OR REPLACE FUNCTION col_type_is ( NAME, NAME, NAME, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
have_type TEXT;
want_type TEXT;
BEGIN
-- Get the data type.
IF $1 IS NULL THEN
have_type := _get_col_type($2, $3);
ELSE
have_type := _get_col_type($1, $2, $3);
END IF;
IF have_type IS NULL THEN
RETURN fail( $5 ) || E'\n' || diag (
' Column ' || COALESCE(quote_ident($1) || '.', '')
|| quote_ident($2) || '.' || quote_ident($3) || ' does not exist'
);
END IF;
want_type := format_type_string($4);
IF want_type IS NULL THEN
RETURN fail( $5 ) || E'\n' || diag (
' Type ' || $4 || ' does not exist'
);
END IF;
IF have_type = want_type THEN
-- We're good to go.
RETURN ok( true, $5 );
END IF;
-- Wrong data type. tell 'em what we really got.
RETURN ok( false, $5 ) || E'\n' || diag(
' have: ' || have_type ||
E'\n want: ' || want_type
);
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION _cmp_types(oid, name)
RETURNS BOOLEAN AS $$
SELECT pg_catalog.format_type($1, NULL) = _typename($2);
$$ LANGUAGE sql;
-- domain_type_is( schema, domain, schema, type, description )
CREATE OR REPLACE FUNCTION domain_type_is( NAME, TEXT, NAME, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
actual_type TEXT := _get_dtype($1, $2, true);
BEGIN
IF actual_type IS NULL THEN
RETURN fail( $5 ) || E'\n' || diag (
' Domain ' || quote_ident($1) || '.' || $2
|| ' does not exist'
);
END IF;
IF quote_ident($3) = ANY(current_schemas(true)) THEN
RETURN is( actual_type, quote_ident($3) || '.' || _typename($4), $5);
END IF;
RETURN is( actual_type, _typename(quote_ident($3) || '.' || $4), $5);
END;
$$ LANGUAGE plpgsql;
-- domain_type_is( schema, domain, type, description )
CREATE OR REPLACE FUNCTION domain_type_is( NAME, TEXT, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
actual_type TEXT := _get_dtype($1, $2, false);
BEGIN
IF actual_type IS NULL THEN
RETURN fail( $4 ) || E'\n' || diag (
' Domain ' || quote_ident($1) || '.' || $2
|| ' does not exist'
);
END IF;
RETURN is( actual_type, _typename($3), $4 );
END;
$$ LANGUAGE plpgsql;
-- domain_type_is( domain, type, description )
CREATE OR REPLACE FUNCTION domain_type_is( TEXT, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
actual_type TEXT := _get_dtype($1);
BEGIN
IF actual_type IS NULL THEN
RETURN fail( $3 ) || E'\n' || diag (
' Domain ' || $1 || ' does not exist'
);
END IF;
RETURN is( actual_type, _typename($2), $3 );
END;
$$ LANGUAGE plpgsql;
-- domain_type_isnt( schema, domain, schema, type, description )
CREATE OR REPLACE FUNCTION domain_type_isnt( NAME, TEXT, NAME, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
actual_type TEXT := _get_dtype($1, $2, true);
BEGIN
IF actual_type IS NULL THEN
RETURN fail( $5 ) || E'\n' || diag (
' Domain ' || quote_ident($1) || '.' || $2
|| ' does not exist'
);
END IF;
IF quote_ident($3) = ANY(current_schemas(true)) THEN
RETURN isnt( actual_type, quote_ident($3) || '.' || _typename($4), $5);
END IF;
RETURN isnt( actual_type, _typename(quote_ident($3) || '.' || $4), $5);
END;
$$ LANGUAGE plpgsql;
-- domain_type_isnt( schema, domain, type, description )
CREATE OR REPLACE FUNCTION domain_type_isnt( NAME, TEXT, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
actual_type TEXT := _get_dtype($1, $2, false);
BEGIN
IF actual_type IS NULL THEN
RETURN fail( $4 ) || E'\n' || diag (
' Domain ' || quote_ident($1) || '.' || $2
|| ' does not exist'
);
END IF;
RETURN isnt( actual_type, _typename($3), $4 );
END;
$$ LANGUAGE plpgsql;
-- domain_type_isnt( domain, type, description )
CREATE OR REPLACE FUNCTION domain_type_isnt( TEXT, TEXT, TEXT )
RETURNS TEXT AS $$
DECLARE
actual_type TEXT := _get_dtype($1);
BEGIN
IF actual_type IS NULL THEN
RETURN fail( $3 ) || E'\n' || diag (
' Domain ' || $1 || ' does not exist'
);
END IF;
RETURN isnt( actual_type, _typename($2), $3 );
END;
$$ LANGUAGE plpgsql;
DROP FUNCTION _quote_ident_like(TEXT, TEXT);
-- has_pk( schema, table )
CREATE OR REPLACE FUNCTION has_pk ( NAME, NAME )
RETURNS TEXT AS $$
SELECT has_pk( $1, $2, 'Table ' || quote_ident($1) || '.' || quote_ident($2) || ' should have a primary key' );
$$ LANGUAGE sql;
|