mirror of
https://github.com/timescale/timescaledb.git
synced 2025-05-17 11:03:36 +08:00
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.
356 lines
17 KiB
Plaintext
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)
|
|
|