timescaledb/test/expected/with_clause_parser.out
Joshua Lockerman 3ef6732b09 Add WITH-clause parser
For a number of DDL statements we want to pass in our own arguments as part of
the WITH statement. This commit adds a parser for such statements, and tests to
ensure that this parser behaves correctly.

Currently, all our WITH options will be namespaced under "timescaledb". In other
words, if we wish to add an option to CREATE INDEX called "foo", it will be used

    CREATE INDEX ... WITH (timescaledb.foo='bar')

This should ensure that all our options are consistent with each other, and that
it is obvious which options are ours, and which are not.
2019-02-22 14:54:36 -05:00

356 lines
17 KiB
Plaintext

\c :TEST_DBNAME :ROLE_SUPERUSER
CREATE OR REPLACE FUNCTION test_with_clause_filter(with_clauses TEXT[][])
RETURNS TABLE(namespace TEXT, name TEXT, value TEXT, filtered BOOLEAN)
AS :MODULE_PATHNAME, 'ts_test_with_clause_filter' LANGUAGE C VOLATILE STRICT;
CREATE OR REPLACE FUNCTION test_with_clause_parse(with_clauses TEXT[][])
RETURNS TABLE(name TEXT, unimpl INT8, bool BOOLEAN, int32 INT4, def INT4, name_arg NAME, regc REGCLASS)
AS :MODULE_PATHNAME, 'ts_test_with_clause_parse' LANGUAGE C VOLATILE STRICT;
\c :TEST_DBNAME :ROLE_DEFAULT_PERM_USER
SELECT * FROM test_with_clause_filter(
'{
{"baz", "bar", "foo"},
{"timescaledb", "bar", "baz"},
{"bar", "timescaledb", "baz"},
{"timescaledb", "baz", "bar"}
}');
namespace | name | value | filtered
-------------+-------------+-------+----------
timescaledb | bar | baz | t
timescaledb | baz | bar | t
baz | bar | foo | f
bar | timescaledb | baz | f
(4 rows)
SELECT * FROM test_with_clause_filter(
'{
{"baz", "bar", "foo"},
{"bar", "timescaledb", "baz"},
{"bar", "timescaledb", "baz"}
}');
namespace | name | value | filtered
-----------+-------------+-------+----------
baz | bar | foo | f
bar | timescaledb | baz | f
bar | timescaledb | baz | f
(3 rows)
SELECT * FROM test_with_clause_filter(
'{
{"bar", "timescaledb"},
{"baz", "bar"},
{"timescaledb", "bar"},
{"timescaledb", "baz"}
}');
namespace | name | value | filtered
-------------+-------------+-------+----------
timescaledb | bar | | t
timescaledb | baz | | t
bar | timescaledb | | f
baz | bar | | f
(4 rows)
SELECT * FROM test_with_clause_filter(
'{
{"timescaledb"},
{"bar"},
{"baz"}
}');
namespace | name | value | filtered
-----------+-------------+-------+----------
| timescaledb | | f
| bar | | f
| baz | | f
(3 rows)
\set ON_ERROR_STOP 0
-- unrecognized argument
SELECT * FROM test_with_clause_parse('{{"timescaledb", "fakearg", "bar"}}');
ERROR: unrecognized parameter "timescaledb.fakearg"
SELECT * FROM test_with_clause_parse('{{"timescaledb", "fakearg"}}');
ERROR: unrecognized parameter "timescaledb.fakearg"
-- unimplemented handled gracefully
SELECT * FROM test_with_clause_parse('{{"timescaledb", "unimplemented", "bar"}}');
ERROR: argument "timescaledb.unimplemented" not implemented
SELECT * FROM test_with_clause_parse('{{"timescaledb", "unimplemented", "true"}}');
ERROR: argument "timescaledb.unimplemented" not implemented
SELECT * FROM test_with_clause_parse('{{"timescaledb", "unimplemented"}}');
ERROR: argument "timescaledb.unimplemented" not implemented
\set ON_ERROR_STOP 1
-- bool parsing
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool", "true"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | t | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool", "false"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | f | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool", "on"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | t | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool", "off"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | f | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool", "1"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | t | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool", "0"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | f | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "bool"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | t | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
-- int32 parsing
SELECT * FROM test_with_clause_parse('{{"timescaledb", "int32", "1"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | 1 | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "int32", "572"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | 572 | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "int32", "-10"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | -10 | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | |
(6 rows)
\set ON_ERROR_STOP 0
SELECT * FROM test_with_clause_parse('{{"timescaledb", "int32", "true"}}');
ERROR: invalid value for timescaledb.int32 'true'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "int32", "bar"}}');
ERROR: invalid value for timescaledb.int32 'bar'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "int32"}}');
ERROR: parameter "timescaledb.int32" must have a value
\set ON_ERROR_STOP 1
-- name parsing
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name", "1"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | 1 |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name", "572"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | 572 |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name", "-10"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | -10 |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name", "true"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | true |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name", "bar"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | bar |
regclass | | | | | |
(6 rows)
\set ON_ERROR_STOP 0
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name"}}');
ERROR: parameter "timescaledb.name" must have a value
\set ON_ERROR_STOP 1
-- REGCLASS parsing
SELECT * FROM test_with_clause_parse('{{"timescaledb", "regclass", "pg_type"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+---------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | | pg_type
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "regclass", "1"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -100 | |
name | | | | | |
regclass | | | | | | 1
(6 rows)
\set ON_ERROR_STOP 0
SELECT * FROM test_with_clause_parse('{{"timescaledb", "regclass", "-10"}}');
ERROR: invalid value for timescaledb.regclass '-10'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "regclass", "true"}}');
ERROR: invalid value for timescaledb.regclass 'true'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "regclass", "bar"}}');
ERROR: invalid value for timescaledb.regclass 'bar'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "regclass"}}');
ERROR: parameter "timescaledb.regclass" must have a value
\set ON_ERROR_STOP 1
-- defaults get overridden
SELECT * FROM test_with_clause_parse('{{"timescaledb", "default", "1"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+-----+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | 1 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "default", "572"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+-----+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | 572 | |
name | | | | | |
regclass | | | | | |
(6 rows)
SELECT * FROM test_with_clause_parse('{{"timescaledb", "default", "-10"}}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+-----+----------+------
unimplemented | | | | | |
bool | | | | | |
int32 | | | | | |
default | | | | -10 | |
name | | | | | |
regclass | | | | | |
(6 rows)
\set ON_ERROR_STOP 0
SELECT * FROM test_with_clause_parse('{{"timescaledb", "default", "true"}}');
ERROR: invalid value for timescaledb.default 'true'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "default", "bar"}}');
ERROR: invalid value for timescaledb.default 'bar'
SELECT * FROM test_with_clause_parse('{{"timescaledb", "default"}}');
ERROR: parameter "timescaledb.default" must have a value
\set ON_ERROR_STOP 1
\set ON_ERROR_STOP 0
-- duplicates error
SELECT * FROM test_with_clause_parse('{{"timescaledb", "name", "1"}, {"timescaledb", "name", "572"}}');
ERROR: duplicate parameter "timescaledb.name"
\set ON_ERROR_STOP 1
-- multiple args
SELECT * FROM test_with_clause_parse('{
{"a", "bool", "true"},
{"b", "int32", "572"},
{"c", "name", "bar"},
{"d", "regclass", "pg_type"}
}');
name | unimpl | bool | int32 | def | name_arg | regc
---------------+--------+------+-------+------+----------+---------
unimplemented | | | | | |
bool | | t | | | |
int32 | | | 572 | | |
default | | | | -100 | |
name | | | | | bar |
regclass | | | | | | pg_type
(6 rows)