From 56e1f40befb1ee7bd3e4c8fa9bfa930da477489b Mon Sep 17 00:00:00 2001 From: "David E. Wheeler" Date: Sun, 17 Sep 2023 21:53:30 -0400 Subject: [PATCH] Improve data type parsing and formatting Add a C module to delegate the parsing of data types by `col_type_is()` to the Postgres core `parseTypeString()` function, which is the canonical type parser. This ensure that no matter the aliasing or typemod specified for a data type, we end up with exactly the same spelling as the core uses, ensuring more accurate comparisons. This was necessitated by the change in 1e1d745 that added support for type aliases but broke complicated typmods such as ` second(0)` in `interval second(0)`. Resolves #315. Document the two new functions, `parse_type()` and `format_type_string()` and remove the documentation for `pg_typeof()`, which hasn't shipped with pgTAP in several years, since it has been in the Postgres core since 8.3. Also, fix the name of the v1.3.9 upgrade file. --- .gitignore | 2 + Changes | 12 + Makefile | 1 + doc/pgtap.mmd | 80 ++-- ...2.0--1.2.1.sql => pgtap--1.2.0--1.3.0.sql} | 0 sql/pgtap--1.3.0--1.3.1.sql | 98 +++++ sql/pgtap.sql.in | 33 +- src/pgtap.c | 88 ++++ test/expected/coltap.out | 401 ++++++++++-------- test/sql/coltap.sql | 126 +++++- 10 files changed, 616 insertions(+), 225 deletions(-) rename sql/{pgtap--1.2.0--1.2.1.sql => pgtap--1.2.0--1.3.0.sql} (100%) create mode 100644 sql/pgtap--1.3.0--1.3.1.sql create mode 100644 src/pgtap.c diff --git a/.gitignore b/.gitignore index fc0b7c6d4..249e89fb2 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ pgtap-schema.sql uninstall_pgtap.sql results pgtap.so +pgtap.dylib +pgtap.dll regression.* *.html *.html1 diff --git a/Changes b/Changes index a7cd06c76..d86606504 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,18 @@ Revision history for pgTAP 1.3.1 -------------------------- +* Revamped the handling of data type declarations in `col_type_is()` to always + accurately normalize data type representations, whether using aliases, such + as `varchar` for `character varying`, or more complicated types that failed + to work in v1.3.0, such as `interval second(0)`. This is done by delegating + the parsing of the type declaration to a core PostgresSQL function. Many + thanks to Erik Wienhold for the report and for ultimately uncovering and + implementing an SQL interface to the `parseTypeString()` core function + (#315). +* Removed the documentation for `pg_typeof()`, which was removed from pgTAP + when support for PostgreSQL 8.3 was dropped, since the same function has + been available in the PostgreSQL core since then. + 1.3.0 2023-08-14T22:14:20Z -------------------------- * Fixed an issue with xUnit tests where they would exit immediately on diff --git a/Makefile b/Makefile index 96a4d11f4..7ce76ccaf 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ EXTRA_CLEAN = $(VERSION_FILES) sql/pgtap.sql sql/uninstall_pgtap.sql sql/pgtap- EXTRA_CLEAN += $(wildcard sql/*.orig) # These are files left behind by patch DOCS = doc/pgtap.mmd PG_CONFIG ?= pg_config +MODULES = src/pgtap # # Test configuration. This must be done BEFORE including PGXS diff --git a/doc/pgtap.mmd b/doc/pgtap.mmd index ec41332fc..c99510a14 100644 --- a/doc/pgtap.mmd +++ b/doc/pgtap.mmd @@ -375,9 +375,9 @@ discrepancy between the planned number of tests and the number actually run: If you need to throw an exception if some test failed, you can pass an option to `finish()`. - - SELECT * FROM finish(true); - + + SELECT * FROM finish(true); + What a sweet unit! ------------------ @@ -4504,22 +4504,24 @@ fourth the type's schema, the fifth the type, and the sixth is the test description. If the table schema is omitted, the table must be visible in the search path. -If the type schema is omitted, it must be visible in the search path; -otherwise, the diagnostics will report the schema it's actually in. The schema -can optionally be included in the `:type` argument, e.g., `'contrib.citext`. +If the type schema is omitted, it must be visible in the search path. The +schema can optionally be included in the `:type` argument, e.g., +`'contrib.citext`. If the test description is omitted, it will be set to "Column `:schema.:table.:column` should be type `:schema.:type`". Note that this test will fail if the table or column in question does not exist. -The type argument should be formatted as it would be displayed in the view of -a table using the `\d` command in `psql`. For example, if you have a numeric -column with a precision of 8, you should specify "numeric(8,0)". If you -created a `varchar(64)` column, you should pass the type as "varchar(64)" or -"character varying(64)". Example: +The type argument should may be formatted using the full name of the type or +any supported alias. For example, if you created a `varchar(64)` column, you +can pass the type as either "varchar(64)" or "character varying(64)". Example: SELECT col_type_is( 'myschema', 'sometable', 'somecolumn', 'numeric(10,2)' ); +Types with case-sensitive names or special characters must be double-quoted: + + SELECT col_type_is( 'myschema', 'sometable', 'somecolumn', '"myType"' ); + If the test fails, it will output useful diagnostics. For example this test: SELECT col_type_is( 'pg_catalog', 'pg_type', 'typname', 'text' ); @@ -4530,8 +4532,8 @@ Will produce something like this: # have: name # want: text -It will even tell you if the test fails because a column doesn't exist or -actually has no default. But use `has_column()` to make sure the column exists +It will even tell you if the test fails because a column doesn't exist or if +the type doesn't exist. But use `has_column()` to make sure the column exists first, eh? ### `col_default_is()` ### @@ -8190,7 +8192,7 @@ the stringified version number displayed in the first part of the core `version()` function and stored in the "server_version" setting: try=% select current_setting( 'server_version'), pg_version(); - current_setting | pg_version + current_setting | pg_version -----------------+------------ 12.2 | 12.2 (1 row) @@ -8273,23 +8275,50 @@ included in the display. For example: Used internally by pgTAP to compare operators, but may be more generally useful. -### `pg_typeof()` ### +### `parse_type()` ### + + SELECT * FROM parse_type( :text ); + +**Parameters** + +`:text` +: An SQL type declaration, optionally schema-qualified. + +Parses a string representing an SQL type declaration as used in a `CREATE +TABLE` statement, optionally schema-qualified. Returns a record with two +fields, `typid` and `typmod`, representing the type OID and type modifier for +the type. These are the underlying values that define column data types, and +which can be passed to the PostgreSQL core +[`format_type()`](https://www.postgresql.org/docs/current/functions-info.html#FUNCTIONS-INFO-CATALOG) +function to display the normalized string representation of the data type. +Raises an error if the specify type does not exist or cannot be found in the +search path. - SELECT pg_typeof(:any); + try=% SELECT format_type(p.typid, p.typmod) + try-% FROM parse_type('timestamp(4)') p; + format_type + -------------------------------- + timestamp(4) without time zone + +### `format_type_string()` ### + + SELECT format_type_string( :text ); **Parameters** -`:any` -: Any SQL value. +`:text` +: An SQL type declaration, optionally schema-qualified. -Returns a `regtype` identifying the type of value passed to the function. This -function is used internally by `cmp_ok()` to properly construct types when -executing the comparison, but might be generally useful. +This function normalizes data type declarations for accurate comparison +to table columns by `col_type_is()`. It's effectively the identical to +the calling `format_type()` with the values returned by `parse_type()`, +but returns a `NULL` on an invalid or missing type, rather than raising +an error. - try=% select pg_typeof(12), pg_typeof(100.2); - pg_typeof | pg_typeof - -----------+----------- - integer | numeric + try=# SELECT format_type_string('timestamp(3)'); + format_type_string + -------------------------------- + timestamp(3) without time zone ### `findfuncs()` ### @@ -8309,7 +8338,6 @@ executing the comparison, but might be generally useful. `:pattern` : Regular expression pattern to exclude functions with matching names. - This function searches the named schema or, if no schema is passed, the search patch, for all functions that match the regular expression pattern. The optional exclude regular expression pattern can be used to prevent matchin diff --git a/sql/pgtap--1.2.0--1.2.1.sql b/sql/pgtap--1.2.0--1.3.0.sql similarity index 100% rename from sql/pgtap--1.2.0--1.2.1.sql rename to sql/pgtap--1.2.0--1.3.0.sql diff --git a/sql/pgtap--1.3.0--1.3.1.sql b/sql/pgtap--1.3.0--1.3.1.sql new file mode 100644 index 000000000..699856458 --- /dev/null +++ b/sql/pgtap--1.3.0--1.3.1.sql @@ -0,0 +1,98 @@ +CREATE FUNCTION parse_type(type text, OUT typid oid, OUT typmod int4) +RETURNS RECORD +AS '$libdir/pgtap' +LANGUAGE C STABLE STRICT; + +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; diff --git a/sql/pgtap.sql.in b/sql/pgtap.sql.in index 36bfe9506..c4c94ccdf 100644 --- a/sql/pgtap.sql.in +++ b/sql/pgtap.sql.in @@ -22,6 +22,11 @@ CREATE OR REPLACE FUNCTION pgtap_version() RETURNS NUMERIC AS 'SELECT __VERSION__;' LANGUAGE SQL IMMUTABLE; +CREATE FUNCTION parse_type(type text, OUT typid oid, OUT typmod int4) +RETURNS RECORD +AS '$libdir/pgtap' +LANGUAGE C STABLE STRICT; + CREATE OR REPLACE FUNCTION plan( integer ) RETURNS TEXT AS $$ DECLARE @@ -1461,6 +1466,13 @@ EXCEPTION WHEN undefined_object THEN RETURN $1; END; $$ LANGUAGE PLPGSQL STABLE; +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; + CREATE OR REPLACE FUNCTION _quote_ident_like(TEXT, TEXT) RETURNS TEXT AS $$ DECLARE @@ -1489,7 +1501,18 @@ BEGIN ); END IF; - want_type := quote_ident($4) || '.' || _quote_ident_like($5, have_type); + 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 ); @@ -1531,7 +1554,13 @@ BEGIN ); END IF; - want_type := _quote_ident_like($4, have_type); + 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 ); diff --git a/src/pgtap.c b/src/pgtap.c new file mode 100644 index 000000000..d83bb419a --- /dev/null +++ b/src/pgtap.c @@ -0,0 +1,88 @@ +/* + * PostgreSQL utility functions for pgTAP. + */ + +#include "postgres.h" +#include "fmgr.h" +#include "funcapi.h" /* for returning composite type */ +#include "utils/builtins.h" /* text_to_cstring() */ +#include "parser/parse_type.h" /* parseTypeString() */ + + +#if PG_VERSION_NUM < 130000 +#include "access/htup_details.h" /* heap_form_tuple() */ +#endif + +#ifdef PG_MODULE_MAGIC +PG_MODULE_MAGIC; +#endif + + +/* + * Given a string that is supposed to be a SQL-compatible type declaration, + * such as "int4" or "integer" or "character varying(32)", parse + * the string and convert it to a type OID and type modifier. + * + * Raises an error on an invalid type. + */ + +/* + * parse_type() is the inverse of pg_catalog.format_type(): it takes a string + * representing an SQL-compatible type declaration, such as "int4" or "integer" + * or "character varying(32)", parses it, and returns the OID and type modifier. + * Returns NULL for an invalid type. + * + * Internally it relies on the Postgres core parseTypeString() function defined + * in src/backend/parser/parse_type.c. + */ +Datum parse_type(PG_FUNCTION_ARGS); + +PG_FUNCTION_INFO_V1(parse_type); + +Datum +parse_type(PG_FUNCTION_ARGS) +{ +#define PARSE_TYPE_STRING_COLS 2 /* Returns two columns. */ + const char *type; /* the type string we want to resolve */ + Oid typid; /* the resolved type oid */ + int32 typmod; /* the resolved type modifier */ + TupleDesc tupdesc; + HeapTuple rettuple; + Datum values[PARSE_TYPE_STRING_COLS] = {0}; + bool nulls[PARSE_TYPE_STRING_COLS] = {0}; + + type = text_to_cstring(PG_GETARG_TEXT_PP(0)); + + /* + * Build a tuple descriptor for our result type; return an error if not + * called in a context that expects a record. + */ + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) { + ereport( + ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context that cannot accept type record")) + ); + } + + BlessTupleDesc(tupdesc); + + /* + * Parse type-name argument to obtain type OID and encoded typmod. We don't + * need to check for parseTypeString failure, but just let the error be + * raised. The 0 arg works both as the `Node *escontext` arg in Postgres 16 + * and the `bool missing_ok` arg in 9.4-15. + */ +#if PG_VERSION_NUM < 90400 + (void) parseTypeString(type, &typid, &typmod); +#else + (void) parseTypeString(type, &typid, &typmod, 0); +#endif + + /* Create and return tuple. */ + values[0] = typid; + values[1] = typmod; + rettuple = heap_form_tuple(tupdesc, values, nulls); + return HeapTupleGetDatum(rettuple); +#undef PARSE_TYPE_STRING_COLS +} diff --git a/test/expected/coltap.out b/test/expected/coltap.out index 73beed974..9a076e773 100644 --- a/test/expected/coltap.out +++ b/test/expected/coltap.out @@ -1,5 +1,5 @@ \unset ECHO -1..243 +1..276 ok 1 - col_not_null( sch, tab, col, desc ) should pass ok 2 - col_not_null( sch, tab, col, desc ) should have the proper description ok 3 - col_not_null( sch, tab, col, desc ) should have the proper diagnostics @@ -57,189 +57,222 @@ ok 54 - col_type_is( sch, tab, myNum, sch, type, desc ) should have the proper d ok 55 - col_type_is( sch, tab, camel, sch, type, desc ) should pass ok 56 - col_type_is( sch, tab, camel, sch, type, desc ) should have the proper description ok 57 - col_type_is( sch, tab, camel, sch, type, desc ) should have the proper diagnostics -ok 58 - col_type_is( sch, tab, camel, sch, type, desc ) should pass -ok 59 - col_type_is( sch, tab, camel, sch, type, desc ) should have the proper description -ok 60 - col_type_is( sch, tab, camel, sch, type, desc ) should have the proper diagnostics +ok 58 - col_type_is( sch, tab, camel, sch, type ) should pass +ok 59 - col_type_is( sch, tab, camel, sch, type ) should have the proper description +ok 60 - col_type_is( sch, tab, camel, sch, type ) should have the proper diagnostics ok 61 - col_type_is( sch, tab, camel, type, desc ) should pass ok 62 - col_type_is( sch, tab, camel, type, desc ) should have the proper description ok 63 - col_type_is( sch, tab, camel, type, desc ) should have the proper diagnostics -ok 64 - col_type_is( sch, tab, col, sch, type, desc ) fail should fail -ok 65 - col_type_is( sch, tab, col, sch, type, desc ) fail should have the proper description -ok 66 - col_type_is( sch, tab, col, sch, type, desc ) fail should have the proper diagnostics -ok 67 - col_type_is( sch, tab, col, sch, non-type, desc ) should fail -ok 68 - col_type_is( sch, tab, col, sch, non-type, desc ) should have the proper description -ok 69 - col_type_is( sch, tab, col, sch, non-type, desc ) should have the proper diagnostics -ok 70 - col_type_is( sch, tab, col, non-sch, type, desc ) should fail -ok 71 - col_type_is( sch, tab, col, non-sch, type, desc ) should have the proper description -ok 72 - col_type_is( sch, tab, col, non-sch, type, desc ) should have the proper diagnostics -ok 73 - col_type_is( sch, tab, non-col, sch, type, desc ) should fail -ok 74 - col_type_is( sch, tab, non-col, sch, type, desc ) should have the proper description -ok 75 - col_type_is( sch, tab, non-col, sch, type, desc ) should have the proper diagnostics -ok 76 - col_type_is( sch, tab, col, type, desc ) should pass -ok 77 - col_type_is( sch, tab, col, type, desc ) should have the proper description -ok 78 - col_type_is( sch, tab, col, type, desc ) should have the proper diagnostics -ok 79 - col_type_is( sch, tab, col, type ) should pass -ok 80 - col_type_is( sch, tab, col, type ) should have the proper description -ok 81 - col_type_is( sch, tab, col, type ) should have the proper diagnostics -ok 82 - col_type_is( tab, col, type, desc ) should pass -ok 83 - col_type_is( tab, col, type, desc ) should have the proper description -ok 84 - col_type_is( tab, col, type, desc ) should have the proper diagnostics -ok 85 - col_type_is( tab, col, type ) should pass -ok 86 - col_type_is( tab, col, type ) should have the proper description -ok 87 - col_type_is( tab, col, type ) should have the proper diagnostics -ok 88 - col_type_is( tab, col, type ) fail should fail -ok 89 - col_type_is( tab, col, type ) fail should have the proper description -ok 90 - col_type_is( tab, col, type ) fail should have the proper diagnostics -ok 91 - col_type_is( tab, noncol, type ) fail should fail -ok 92 - col_type_is( tab, noncol, type ) fail should have the proper description -ok 93 - col_type_is( tab, noncol, type ) fail should have the proper diagnostics -ok 94 - col_type_is( sch, tab, noncol, type, desc ) fail should fail -ok 95 - col_type_is( sch, tab, noncol, type, desc ) fail should have the proper description -ok 96 - col_type_is( sch, tab, noncol, type, desc ) fail should have the proper diagnostics -ok 97 - col_type_is with precision should pass -ok 98 - col_type_is with precision should have the proper description -ok 99 - col_type_is with precision should have the proper diagnostics -ok 100 - col_type_is precision fail should fail -ok 101 - col_type_is precision fail should have the proper description -ok 102 - col_type_is precision fail should have the proper diagnostics -ok 103 - col_has_default( sch, tab, col, desc ) should pass -ok 104 - col_has_default( sch, tab, col, desc ) should have the proper description -ok 105 - col_has_default( sch, tab, col, desc ) should have the proper diagnostics -ok 106 - col_has_default( tab, col, desc ) should pass -ok 107 - col_has_default( tab, col, desc ) should have the proper description -ok 108 - col_has_default( tab, col, desc ) should have the proper diagnostics -ok 109 - col_has_default( tab, col ) should pass -ok 110 - col_has_default( tab, col ) should have the proper description -ok 111 - col_has_default( tab, col ) should have the proper diagnostics -ok 112 - col_has_default( sch, tab, col, desc ) should fail -ok 113 - col_has_default( sch, tab, col, desc ) should have the proper description -ok 114 - col_has_default( sch, tab, col, desc ) should have the proper diagnostics -ok 115 - col_has_default( tab, col, desc ) should fail -ok 116 - col_has_default( tab, col, desc ) should have the proper description -ok 117 - col_has_default( tab, col, desc ) should have the proper diagnostics -ok 118 - col_has_default( tab, col ) should fail -ok 119 - col_has_default( tab, col ) should have the proper description -ok 120 - col_has_default( tab, col ) should have the proper diagnostics -ok 121 - col_has_default( sch, tab, col, desc ) should fail -ok 122 - col_has_default( sch, tab, col, desc ) should have the proper description -ok 123 - col_has_default( sch, tab, col, desc ) should have the proper diagnostics -ok 124 - col_has_default( tab, col, desc ) should fail -ok 125 - col_has_default( tab, col, desc ) should have the proper description -ok 126 - col_has_default( tab, col, desc ) should have the proper diagnostics -ok 127 - col_has_default( tab, col ) should fail -ok 128 - col_has_default( tab, col ) should have the proper description -ok 129 - col_has_default( tab, col ) should have the proper diagnostics -ok 130 - col_hasnt_default( sch, tab, col, desc ) should fail -ok 131 - col_hasnt_default( sch, tab, col, desc ) should have the proper description -ok 132 - col_hasnt_default( sch, tab, col, desc ) should have the proper diagnostics -ok 133 - col_hasnt_default( tab, col, desc ) should fail -ok 134 - col_hasnt_default( tab, col, desc ) should have the proper description -ok 135 - col_hasnt_default( tab, col, desc ) should have the proper diagnostics -ok 136 - col_hasnt_default( tab, col ) should fail -ok 137 - col_hasnt_default( tab, col ) should have the proper description -ok 138 - col_hasnt_default( tab, col ) should have the proper diagnostics -ok 139 - col_hasnt_default( sch, tab, col, desc ) should pass -ok 140 - col_hasnt_default( sch, tab, col, desc ) should have the proper description -ok 141 - col_hasnt_default( sch, tab, col, desc ) should have the proper diagnostics -ok 142 - col_hasnt_default( tab, col, desc ) should pass -ok 143 - col_hasnt_default( tab, col, desc ) should have the proper description -ok 144 - col_hasnt_default( tab, col, desc ) should have the proper diagnostics -ok 145 - col_hasnt_default( tab, col ) should pass -ok 146 - col_hasnt_default( tab, col ) should have the proper description -ok 147 - col_hasnt_default( tab, col ) should have the proper diagnostics -ok 148 - col_hasnt_default( sch, tab, col, desc ) should fail -ok 149 - col_hasnt_default( sch, tab, col, desc ) should have the proper description -ok 150 - col_hasnt_default( sch, tab, col, desc ) should have the proper diagnostics -ok 151 - col_hasnt_default( tab, col, desc ) should fail -ok 152 - col_hasnt_default( tab, col, desc ) should have the proper description -ok 153 - col_hasnt_default( tab, col, desc ) should have the proper diagnostics -ok 154 - col_hasnt_default( tab, col ) should fail -ok 155 - col_hasnt_default( tab, col ) should have the proper description -ok 156 - col_hasnt_default( tab, col ) should have the proper diagnostics -ok 157 - col_default_is( sch, tab, col, def, desc ) should pass -ok 158 - col_default_is( sch, tab, col, def, desc ) should have the proper description -ok 159 - col_default_is( sch, tab, col, def, desc ) should have the proper diagnostics -ok 160 - col_default_is() fail should fail -ok 161 - col_default_is() fail should have the proper description -ok 162 - col_default_is() fail should have the proper diagnostics -ok 163 - col_default_is( tab, col, def, desc ) should pass -ok 164 - col_default_is( tab, col, def, desc ) should have the proper description -ok 165 - col_default_is( tab, col, def, desc ) should have the proper diagnostics -ok 166 - col_default_is( tab, col, def ) should pass -ok 167 - col_default_is( tab, col, def ) should have the proper description -ok 168 - col_default_is( tab, col, def ) should have the proper diagnostics -ok 169 - col_default_is( tab, col, int ) should pass -ok 170 - col_default_is( tab, col, int ) should have the proper description -ok 171 - col_default_is( tab, col, int ) should have the proper diagnostics -ok 172 - col_default_is( tab, col, NULL, desc ) should pass -ok 173 - col_default_is( tab, col, NULL, desc ) should have the proper description -ok 174 - col_default_is( tab, col, NULL, desc ) should have the proper diagnostics -ok 175 - col_default_is( tab, col, NULL ) should pass -ok 176 - col_default_is( tab, col, NULL ) should have the proper description -ok 177 - col_default_is( tab, col, NULL ) should have the proper diagnostics -ok 178 - col_default_is( tab, col, bogus, desc ) should fail -ok 179 - col_default_is( tab, col, bogus, desc ) should have the proper description -ok 180 - col_default_is( tab, col, bogus, desc ) should have the proper diagnostics -ok 181 - col_default_is( tab, col, bogus ) should fail -ok 182 - col_default_is( tab, col, bogus ) should have the proper description -ok 183 - col_default_is( tab, col, bogus ) should have the proper diagnostics -ok 184 - col_default_is( tab, col, expression ) should pass -ok 185 - col_default_is( tab, col, expression ) should have the proper description -ok 186 - col_default_is( tab, col, expression ) should have the proper diagnostics -ok 187 - col_default_is( tab, col, expression::text ) should pass -ok 188 - col_default_is( tab, col, expression::text ) should have the proper description -ok 189 - col_default_is( tab, col, expression::text ) should have the proper diagnostics -ok 190 - col_default_is( tab, col, expression, desc ) should pass -ok 191 - col_default_is( tab, col, expression, desc ) should have the proper description -ok 192 - col_default_is( tab, col, expression, desc ) should have the proper diagnostics -ok 193 - col_default_is( tab, col, expression, desc ) should pass -ok 194 - col_default_is( tab, col, expression, desc ) should have the proper description -ok 195 - col_default_is( tab, col, expression, desc ) should have the proper diagnostics -ok 196 - col_default_is( schema, tab, col, expression, desc ) should pass -ok 197 - col_default_is( schema, tab, col, expression, desc ) should have the proper description -ok 198 - col_default_is( schema, tab, col, expression, desc ) should have the proper diagnostics -ok 199 - col_default_is( schema, tab, col, expression, desc ) should pass -ok 200 - col_default_is( schema, tab, col, expression, desc ) should have the proper description -ok 201 - col_default_is( schema, tab, col, expression, desc ) should have the proper diagnostics -ok 202 - col_default_is( sch, tab, col, def, desc ) should fail -ok 203 - col_default_is( sch, tab, col, def, desc ) should have the proper description -ok 204 - col_default_is( sch, tab, col, def, desc ) should have the proper diagnostics -ok 205 - col_default_is( tab, col, def, desc ) should fail -ok 206 - col_default_is( tab, col, def, desc ) should have the proper description -ok 207 - col_default_is( tab, col, def, desc ) should have the proper diagnostics -ok 208 - col_default_is( tab, col, def ) should fail -ok 209 - col_default_is( tab, col, def ) should have the proper description -ok 210 - col_default_is( tab, col, def ) should have the proper diagnostics -ok 211 - col_default_is( tab, col, CURRENT_CATALOG ) should pass -ok 212 - col_default_is( tab, col, CURRENT_CATALOG ) should have the proper description -ok 213 - col_default_is( tab, col, CURRENT_CATALOG ) should have the proper diagnostics -ok 214 - col_default_is( tab, col, CURRENT_ROLE ) should pass -ok 215 - col_default_is( tab, col, CURRENT_ROLE ) should have the proper description -ok 216 - col_default_is( tab, col, CURRENT_ROLE ) should have the proper diagnostics -ok 217 - col_default_is( tab, col, CURRENT_SCHEMA ) should pass -ok 218 - col_default_is( tab, col, CURRENT_SCHEMA ) should have the proper description -ok 219 - col_default_is( tab, col, CURRENT_SCHEMA ) should have the proper diagnostics -ok 220 - col_default_is( tab, col, CURRENT_USER ) should pass -ok 221 - col_default_is( tab, col, CURRENT_USER ) should have the proper description -ok 222 - col_default_is( tab, col, CURRENT_USER ) should have the proper diagnostics -ok 223 - col_default_is( tab, col, SESSION_USER ) should pass -ok 224 - col_default_is( tab, col, SESSION_USER ) should have the proper description -ok 225 - col_default_is( tab, col, SESSION_USER ) should have the proper diagnostics -ok 226 - col_default_is( tab, col, USER ) should pass -ok 227 - col_default_is( tab, col, USER ) should have the proper description -ok 228 - col_default_is( tab, col, USER ) should have the proper diagnostics -ok 229 - col_default_is( tab, col, CURRENT_DATE ) should pass -ok 230 - col_default_is( tab, col, CURRENT_DATE ) should have the proper description -ok 231 - col_default_is( tab, col, CURRENT_DATE ) should have the proper diagnostics -ok 232 - col_default_is( tab, col, CURRENT_TIME ) should pass -ok 233 - col_default_is( tab, col, CURRENT_TIME ) should have the proper description -ok 234 - col_default_is( tab, col, CURRENT_TIME ) should have the proper diagnostics -ok 235 - col_default_is( tab, col, CURRENT_TIMESTAMP ) should pass -ok 236 - col_default_is( tab, col, CURRENT_TIMESTAMP ) should have the proper description -ok 237 - col_default_is( tab, col, CURRENT_TIMESTAMP ) should have the proper diagnostics -ok 238 - col_default_is( tab, col, LOCALTIME ) should pass -ok 239 - col_default_is( tab, col, LOCALTIME ) should have the proper description -ok 240 - col_default_is( tab, col, LOCALTIME ) should have the proper diagnostics -ok 241 - col_default_is( tab, col, LOCALTIMESTAMP ) should pass -ok 242 - col_default_is( tab, col, LOCALTIMESTAMP ) should have the proper description -ok 243 - col_default_is( tab, col, LOCALTIMESTAMP ) should have the proper diagnostics +ok 64 - col_type_is( sch, tab, interval, sch, type, desc ) should pass +ok 65 - col_type_is( sch, tab, interval, sch, type, desc ) should have the proper description +ok 66 - col_type_is( sch, tab, interval, sch, type, desc ) should have the proper diagnostics +ok 67 - col_type_is( sch, tab, interval, sch, type, desc ) should pass +ok 68 - col_type_is( sch, tab, interval, sch, type, desc ) should have the proper description +ok 69 - col_type_is( sch, tab, interval, sch, type, desc ) should have the proper diagnostics +ok 70 - col_type_is( sch, tab, inval, type, desc ) should pass +ok 71 - col_type_is( sch, tab, inval, type, desc ) should have the proper description +ok 72 - col_type_is( sch, tab, inval, type, desc ) should have the proper diagnostics +ok 73 - col_type_is( sch, tab, intsec, sch, type, desc ) should pass +ok 74 - col_type_is( sch, tab, intsec, sch, type, desc ) should have the proper description +ok 75 - col_type_is( sch, tab, intsec, sch, type, desc ) should have the proper diagnostics +ok 76 - col_type_is( sch, tab, interval, sch, type, desc ) should pass +ok 77 - col_type_is( sch, tab, interval, sch, type, desc ) should have the proper description +ok 78 - col_type_is( sch, tab, interval, sch, type, desc ) should have the proper diagnostics +ok 79 - col_type_is( sch, tab, inval, type, desc ) should pass +ok 80 - col_type_is( sch, tab, inval, type, desc ) should have the proper description +ok 81 - col_type_is( sch, tab, inval, type, desc ) should have the proper diagnostics +ok 82 - col_type_is( sch, tab, stuff, sch, type, desc ) should pass +ok 83 - col_type_is( sch, tab, stuff, sch, type, desc ) should have the proper description +ok 84 - col_type_is( sch, tab, stuff, sch, type, desc ) should have the proper diagnostics +ok 85 - col_type_is( sch, tab, stuff, sch, type, desc ) should pass +ok 86 - col_type_is( sch, tab, stuff, sch, type, desc ) should have the proper description +ok 87 - col_type_is( sch, tab, stuff, sch, type, desc ) should have the proper diagnostics +ok 88 - col_type_is( sch, tab, col, sch, type, desc ) fail should fail +ok 89 - col_type_is( sch, tab, col, sch, type, desc ) fail should have the proper description +ok 90 - col_type_is( sch, tab, col, sch, type, desc ) fail should have the proper diagnostics +ok 91 - col_type_is( sch, tab, col, sch, non-type, desc ) should fail +ok 92 - col_type_is( sch, tab, col, sch, non-type, desc ) should have the proper description +ok 93 - col_type_is( sch, tab, col, sch, non-type, desc ) should have the proper diagnostics +ok 94 - col_type_is( sch, tab, col, non-sch, type, desc ) should fail +ok 95 - col_type_is( sch, tab, col, non-sch, type, desc ) should have the proper description +ok 96 - col_type_is( sch, tab, col, non-sch, type, desc ) should have the proper diagnostics +ok 97 - col_type_is( sch, tab, col, non-sch, type, desc ) should fail +ok 98 - col_type_is( sch, tab, col, non-sch, type, desc ) should have the proper description +ok 99 - col_type_is( sch, tab, col, non-sch, type, desc ) should have the proper diagnostics +ok 100 - col_type_is( sch, tab, col, non-type, desc ) should fail +ok 101 - col_type_is( sch, tab, col, non-type, desc ) should have the proper description +ok 102 - col_type_is( sch, tab, col, non-type, desc ) should have the proper diagnostics +ok 103 - col_type_is( tab, col, non-type, desc ) should fail +ok 104 - col_type_is( tab, col, non-type, desc ) should have the proper description +ok 105 - col_type_is( tab, col, non-type, desc ) should have the proper diagnostics +ok 106 - col_type_is( sch, tab, non-col, sch, type, desc ) should fail +ok 107 - col_type_is( sch, tab, non-col, sch, type, desc ) should have the proper description +ok 108 - col_type_is( sch, tab, non-col, sch, type, desc ) should have the proper diagnostics +ok 109 - col_type_is( sch, tab, col, type, desc ) should pass +ok 110 - col_type_is( sch, tab, col, type, desc ) should have the proper description +ok 111 - col_type_is( sch, tab, col, type, desc ) should have the proper diagnostics +ok 112 - col_type_is( sch, tab, col, type ) should pass +ok 113 - col_type_is( sch, tab, col, type ) should have the proper description +ok 114 - col_type_is( sch, tab, col, type ) should have the proper diagnostics +ok 115 - col_type_is( tab, col, type, desc ) should pass +ok 116 - col_type_is( tab, col, type, desc ) should have the proper description +ok 117 - col_type_is( tab, col, type, desc ) should have the proper diagnostics +ok 118 - col_type_is( tab, col, type ) should pass +ok 119 - col_type_is( tab, col, type ) should have the proper description +ok 120 - col_type_is( tab, col, type ) should have the proper diagnostics +ok 121 - col_type_is( tab, col, type ) fail should fail +ok 122 - col_type_is( tab, col, type ) fail should have the proper description +ok 123 - col_type_is( tab, col, type ) fail should have the proper diagnostics +ok 124 - col_type_is( tab, noncol, type ) fail should fail +ok 125 - col_type_is( tab, noncol, type ) fail should have the proper description +ok 126 - col_type_is( tab, noncol, type ) fail should have the proper diagnostics +ok 127 - col_type_is( sch, tab, noncol, type, desc ) fail should fail +ok 128 - col_type_is( sch, tab, noncol, type, desc ) fail should have the proper description +ok 129 - col_type_is( sch, tab, noncol, type, desc ) fail should have the proper diagnostics +ok 130 - col_type_is with precision should pass +ok 131 - col_type_is with precision should have the proper description +ok 132 - col_type_is with precision should have the proper diagnostics +ok 133 - col_type_is precision fail should fail +ok 134 - col_type_is precision fail should have the proper description +ok 135 - col_type_is precision fail should have the proper diagnostics +ok 136 - col_has_default( sch, tab, col, desc ) should pass +ok 137 - col_has_default( sch, tab, col, desc ) should have the proper description +ok 138 - col_has_default( sch, tab, col, desc ) should have the proper diagnostics +ok 139 - col_has_default( tab, col, desc ) should pass +ok 140 - col_has_default( tab, col, desc ) should have the proper description +ok 141 - col_has_default( tab, col, desc ) should have the proper diagnostics +ok 142 - col_has_default( tab, col ) should pass +ok 143 - col_has_default( tab, col ) should have the proper description +ok 144 - col_has_default( tab, col ) should have the proper diagnostics +ok 145 - col_has_default( sch, tab, col, desc ) should fail +ok 146 - col_has_default( sch, tab, col, desc ) should have the proper description +ok 147 - col_has_default( sch, tab, col, desc ) should have the proper diagnostics +ok 148 - col_has_default( tab, col, desc ) should fail +ok 149 - col_has_default( tab, col, desc ) should have the proper description +ok 150 - col_has_default( tab, col, desc ) should have the proper diagnostics +ok 151 - col_has_default( tab, col ) should fail +ok 152 - col_has_default( tab, col ) should have the proper description +ok 153 - col_has_default( tab, col ) should have the proper diagnostics +ok 154 - col_has_default( sch, tab, col, desc ) should fail +ok 155 - col_has_default( sch, tab, col, desc ) should have the proper description +ok 156 - col_has_default( sch, tab, col, desc ) should have the proper diagnostics +ok 157 - col_has_default( tab, col, desc ) should fail +ok 158 - col_has_default( tab, col, desc ) should have the proper description +ok 159 - col_has_default( tab, col, desc ) should have the proper diagnostics +ok 160 - col_has_default( tab, col ) should fail +ok 161 - col_has_default( tab, col ) should have the proper description +ok 162 - col_has_default( tab, col ) should have the proper diagnostics +ok 163 - col_hasnt_default( sch, tab, col, desc ) should fail +ok 164 - col_hasnt_default( sch, tab, col, desc ) should have the proper description +ok 165 - col_hasnt_default( sch, tab, col, desc ) should have the proper diagnostics +ok 166 - col_hasnt_default( tab, col, desc ) should fail +ok 167 - col_hasnt_default( tab, col, desc ) should have the proper description +ok 168 - col_hasnt_default( tab, col, desc ) should have the proper diagnostics +ok 169 - col_hasnt_default( tab, col ) should fail +ok 170 - col_hasnt_default( tab, col ) should have the proper description +ok 171 - col_hasnt_default( tab, col ) should have the proper diagnostics +ok 172 - col_hasnt_default( sch, tab, col, desc ) should pass +ok 173 - col_hasnt_default( sch, tab, col, desc ) should have the proper description +ok 174 - col_hasnt_default( sch, tab, col, desc ) should have the proper diagnostics +ok 175 - col_hasnt_default( tab, col, desc ) should pass +ok 176 - col_hasnt_default( tab, col, desc ) should have the proper description +ok 177 - col_hasnt_default( tab, col, desc ) should have the proper diagnostics +ok 178 - col_hasnt_default( tab, col ) should pass +ok 179 - col_hasnt_default( tab, col ) should have the proper description +ok 180 - col_hasnt_default( tab, col ) should have the proper diagnostics +ok 181 - col_hasnt_default( sch, tab, col, desc ) should fail +ok 182 - col_hasnt_default( sch, tab, col, desc ) should have the proper description +ok 183 - col_hasnt_default( sch, tab, col, desc ) should have the proper diagnostics +ok 184 - col_hasnt_default( tab, col, desc ) should fail +ok 185 - col_hasnt_default( tab, col, desc ) should have the proper description +ok 186 - col_hasnt_default( tab, col, desc ) should have the proper diagnostics +ok 187 - col_hasnt_default( tab, col ) should fail +ok 188 - col_hasnt_default( tab, col ) should have the proper description +ok 189 - col_hasnt_default( tab, col ) should have the proper diagnostics +ok 190 - col_default_is( sch, tab, col, def, desc ) should pass +ok 191 - col_default_is( sch, tab, col, def, desc ) should have the proper description +ok 192 - col_default_is( sch, tab, col, def, desc ) should have the proper diagnostics +ok 193 - col_default_is() fail should fail +ok 194 - col_default_is() fail should have the proper description +ok 195 - col_default_is() fail should have the proper diagnostics +ok 196 - col_default_is( tab, col, def, desc ) should pass +ok 197 - col_default_is( tab, col, def, desc ) should have the proper description +ok 198 - col_default_is( tab, col, def, desc ) should have the proper diagnostics +ok 199 - col_default_is( tab, col, def ) should pass +ok 200 - col_default_is( tab, col, def ) should have the proper description +ok 201 - col_default_is( tab, col, def ) should have the proper diagnostics +ok 202 - col_default_is( tab, col, int ) should pass +ok 203 - col_default_is( tab, col, int ) should have the proper description +ok 204 - col_default_is( tab, col, int ) should have the proper diagnostics +ok 205 - col_default_is( tab, col, NULL, desc ) should pass +ok 206 - col_default_is( tab, col, NULL, desc ) should have the proper description +ok 207 - col_default_is( tab, col, NULL, desc ) should have the proper diagnostics +ok 208 - col_default_is( tab, col, NULL ) should pass +ok 209 - col_default_is( tab, col, NULL ) should have the proper description +ok 210 - col_default_is( tab, col, NULL ) should have the proper diagnostics +ok 211 - col_default_is( tab, col, bogus, desc ) should fail +ok 212 - col_default_is( tab, col, bogus, desc ) should have the proper description +ok 213 - col_default_is( tab, col, bogus, desc ) should have the proper diagnostics +ok 214 - col_default_is( tab, col, bogus ) should fail +ok 215 - col_default_is( tab, col, bogus ) should have the proper description +ok 216 - col_default_is( tab, col, bogus ) should have the proper diagnostics +ok 217 - col_default_is( tab, col, expression ) should pass +ok 218 - col_default_is( tab, col, expression ) should have the proper description +ok 219 - col_default_is( tab, col, expression ) should have the proper diagnostics +ok 220 - col_default_is( tab, col, expression::text ) should pass +ok 221 - col_default_is( tab, col, expression::text ) should have the proper description +ok 222 - col_default_is( tab, col, expression::text ) should have the proper diagnostics +ok 223 - col_default_is( tab, col, expression, desc ) should pass +ok 224 - col_default_is( tab, col, expression, desc ) should have the proper description +ok 225 - col_default_is( tab, col, expression, desc ) should have the proper diagnostics +ok 226 - col_default_is( tab, col, expression, desc ) should pass +ok 227 - col_default_is( tab, col, expression, desc ) should have the proper description +ok 228 - col_default_is( tab, col, expression, desc ) should have the proper diagnostics +ok 229 - col_default_is( schema, tab, col, expression, desc ) should pass +ok 230 - col_default_is( schema, tab, col, expression, desc ) should have the proper description +ok 231 - col_default_is( schema, tab, col, expression, desc ) should have the proper diagnostics +ok 232 - col_default_is( schema, tab, col, expression, desc ) should pass +ok 233 - col_default_is( schema, tab, col, expression, desc ) should have the proper description +ok 234 - col_default_is( schema, tab, col, expression, desc ) should have the proper diagnostics +ok 235 - col_default_is( sch, tab, col, def, desc ) should fail +ok 236 - col_default_is( sch, tab, col, def, desc ) should have the proper description +ok 237 - col_default_is( sch, tab, col, def, desc ) should have the proper diagnostics +ok 238 - col_default_is( tab, col, def, desc ) should fail +ok 239 - col_default_is( tab, col, def, desc ) should have the proper description +ok 240 - col_default_is( tab, col, def, desc ) should have the proper diagnostics +ok 241 - col_default_is( tab, col, def ) should fail +ok 242 - col_default_is( tab, col, def ) should have the proper description +ok 243 - col_default_is( tab, col, def ) should have the proper diagnostics +ok 244 - col_default_is( tab, col, CURRENT_CATALOG ) should pass +ok 245 - col_default_is( tab, col, CURRENT_CATALOG ) should have the proper description +ok 246 - col_default_is( tab, col, CURRENT_CATALOG ) should have the proper diagnostics +ok 247 - col_default_is( tab, col, CURRENT_ROLE ) should pass +ok 248 - col_default_is( tab, col, CURRENT_ROLE ) should have the proper description +ok 249 - col_default_is( tab, col, CURRENT_ROLE ) should have the proper diagnostics +ok 250 - col_default_is( tab, col, CURRENT_SCHEMA ) should pass +ok 251 - col_default_is( tab, col, CURRENT_SCHEMA ) should have the proper description +ok 252 - col_default_is( tab, col, CURRENT_SCHEMA ) should have the proper diagnostics +ok 253 - col_default_is( tab, col, CURRENT_USER ) should pass +ok 254 - col_default_is( tab, col, CURRENT_USER ) should have the proper description +ok 255 - col_default_is( tab, col, CURRENT_USER ) should have the proper diagnostics +ok 256 - col_default_is( tab, col, SESSION_USER ) should pass +ok 257 - col_default_is( tab, col, SESSION_USER ) should have the proper description +ok 258 - col_default_is( tab, col, SESSION_USER ) should have the proper diagnostics +ok 259 - col_default_is( tab, col, USER ) should pass +ok 260 - col_default_is( tab, col, USER ) should have the proper description +ok 261 - col_default_is( tab, col, USER ) should have the proper diagnostics +ok 262 - col_default_is( tab, col, CURRENT_DATE ) should pass +ok 263 - col_default_is( tab, col, CURRENT_DATE ) should have the proper description +ok 264 - col_default_is( tab, col, CURRENT_DATE ) should have the proper diagnostics +ok 265 - col_default_is( tab, col, CURRENT_TIME ) should pass +ok 266 - col_default_is( tab, col, CURRENT_TIME ) should have the proper description +ok 267 - col_default_is( tab, col, CURRENT_TIME ) should have the proper diagnostics +ok 268 - col_default_is( tab, col, CURRENT_TIMESTAMP ) should pass +ok 269 - col_default_is( tab, col, CURRENT_TIMESTAMP ) should have the proper description +ok 270 - col_default_is( tab, col, CURRENT_TIMESTAMP ) should have the proper diagnostics +ok 271 - col_default_is( tab, col, LOCALTIME ) should pass +ok 272 - col_default_is( tab, col, LOCALTIME ) should have the proper description +ok 273 - col_default_is( tab, col, LOCALTIME ) should have the proper diagnostics +ok 274 - col_default_is( tab, col, LOCALTIMESTAMP ) should pass +ok 275 - col_default_is( tab, col, LOCALTIMESTAMP ) should have the proper description +ok 276 - col_default_is( tab, col, LOCALTIMESTAMP ) should have the proper diagnostics diff --git a/test/sql/coltap.sql b/test/sql/coltap.sql index 5674f751d..2a0a9af25 100644 --- a/test/sql/coltap.sql +++ b/test/sql/coltap.sql @@ -1,14 +1,21 @@ \unset ECHO \i test/setup.sql +-- \i sql/pgtap.sql -SELECT plan(243); ---SELECT * from no_plan(); +SELECT plan(276); +-- SELECT * from no_plan(); CREATE TYPE public."myType" AS ( id INT, foo INT ); +CREATE SCHEMA hidden; +CREATE TYPE hidden.stuff AS ( + id INT, + foo INT +); + -- This will be rolled back. :-) SET client_min_messages = warning; CREATE TABLE public.sometab( @@ -29,7 +36,11 @@ CREATE TABLE public.sometab( ltime TIME DEFAULT LOCALTIME, ltstz TIMESTAMPTZ DEFAULT LOCALTIMESTAMP, plain INTEGER, - camel "myType" + camel "myType", + inval INTERVAL(0), + isecd INTERVAL SECOND(0), + iyear INTERVAL YEAR, + stuff hidden.stuff ); CREATE OR REPLACE FUNCTION fakeout( eok boolean, name text ) @@ -201,7 +212,7 @@ SELECT * FROM check_test( -- Try case-sensitive type name. SELECT * FROM check_test( - col_type_is( 'public', 'sometab', 'camel', 'public', 'myType', 'camel is myType' ), + col_type_is( 'public', 'sometab', 'camel', 'public', '"myType"', 'camel is myType' ), true, 'col_type_is( sch, tab, camel, sch, type, desc )', 'camel is myType', @@ -209,21 +220,88 @@ SELECT * FROM check_test( ); SELECT * FROM check_test( - col_type_is( 'public', 'sometab', 'camel', 'public'::name, 'myType' ), + col_type_is( 'public', 'sometab', 'camel', 'public'::name, '"myType"' ), true, - 'col_type_is( sch, tab, camel, sch, type, desc )', - 'Column public.sometab.camel should be type public.myType', + 'col_type_is( sch, tab, camel, sch, type )', + 'Column public.sometab.camel should be type public."myType"', '' ); SELECT * FROM check_test( - col_type_is( 'public', 'sometab', 'camel', 'myType', 'whatever' ), + col_type_is( 'public', 'sometab', 'camel', '"myType"', 'whatever' ), true, 'col_type_is( sch, tab, camel, type, desc )', 'whatever', '' ); +-- Try interval. +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'inval', 'pg_catalog', 'interval(0)', 'inval is interval(0)' ), + true, + 'col_type_is( sch, tab, interval, sch, type, desc )', + 'inval is interval(0)', + '' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'inval', 'pg_catalog'::name, 'interval(0)' ), + true, + 'col_type_is( sch, tab, interval, sch, type, desc )', + 'Column public.sometab.inval should be type pg_catalog.interval(0)', + '' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'inval', 'interval(0)', 'whatever' ), + true, + 'col_type_is( sch, tab, inval, type, desc )', + 'whatever', + '' +); + +-- Try interval second. +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'isecd', 'pg_catalog', 'interval second(0)', 'isecd is interval second(0)' ), + true, + 'col_type_is( sch, tab, intsec, sch, type, desc )', + 'isecd is interval second(0)', + '' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'inval', 'pg_catalog'::name, 'interval(0)' ), + true, + 'col_type_is( sch, tab, interval, sch, type, desc )', + 'Column public.sometab.inval should be type pg_catalog.interval(0)', + '' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'inval', 'interval(0)', 'whatever' ), + true, + 'col_type_is( sch, tab, inval, type, desc )', + 'whatever', + '' +); + +-- Try type not in search path. +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'stuff', 'hidden', 'stuff', 'stuff is stuff' ), + true, + 'col_type_is( sch, tab, stuff, sch, type, desc )', + 'stuff is stuff', + '' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'stuff', 'hidden'::name, 'stuff' ), + true, + 'col_type_is( sch, tab, stuff, sch, type, desc )', + 'Column public.sometab.stuff should be type hidden.stuff', + '' +); + -- Try failures. SELECT * FROM check_test( col_type_is( 'public', 'sometab', 'name', 'pg_catalog', 'int', 'whatever' ), @@ -239,8 +317,7 @@ SELECT * FROM check_test( false, 'col_type_is( sch, tab, col, sch, non-type, desc )', 'whatever', - ' have: pg_catalog.text - want: pg_catalog.blech' + ' Type pg_catalog.blech does not exist' ); SELECT * FROM check_test( @@ -248,8 +325,31 @@ SELECT * FROM check_test( false, 'col_type_is( sch, tab, col, non-sch, type, desc )', 'whatever', - ' have: pg_catalog.text - want: fooey.text' + ' Type fooey.text does not exist' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'name', 'fooey', 'text', 'whatever' ), + false, + 'col_type_is( sch, tab, col, non-sch, type, desc )', + 'whatever', + ' Type fooey.text does not exist' +); + +SELECT * FROM check_test( + col_type_is( 'public', 'sometab', 'name', 'nonesuch', 'whatever' ), + false, + 'col_type_is( sch, tab, col, non-type, desc )', + 'whatever', + ' Type nonesuch does not exist' +); + +SELECT * FROM check_test( + col_type_is( 'sometab', 'name', 'nonesuch', 'whatever' ), + false, + 'col_type_is( tab, col, non-type, desc )', + 'whatever', + ' Type nonesuch does not exist' ); SELECT * FROM check_test( @@ -336,7 +436,7 @@ SELECT * FROM check_test( 'col_type_is precision fail', 'should be numeric(7)', ' have: numeric(8,0) - want: numeric(7)' + want: numeric(7,0)' ); /****************************************************************************/