Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 40 additions & 6 deletions crates/squawk_parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12839,11 +12839,6 @@ fn drop_schema(p: &mut Parser<'_>) -> CompletedMarker {
}

// An SQL statement defining an object to be created within the schema.
//
// Currently, only CREATE TABLE, CREATE VIEW, CREATE INDEX, CREATE SEQUENCE,
// CREATE TRIGGER and GRANT are accepted as clauses within CREATE SCHEMA. Other
// kinds of objects may be created in separate commands after the schema is
// created.
fn opt_schema_elements(p: &mut Parser<'_>) {
while !p.at(EOF) {
match (p.current(), p.nth(1)) {
Expand All @@ -12864,9 +12859,11 @@ fn opt_schema_elements(p: &mut Parser<'_>) {
}
(CREATE_KW, OR_KW) => {
match p.nth(3) {
AGGREGATE_KW => create_aggregate(p),
CONSTRAINT_KW | TRIGGER_KW => create_trigger(p),
PROCEDURE_KW => create_procedure(p),
RECURSIVE_KW | TEMP_KW | TEMPORARY_KW | VIEW_KW => create_view(p),
_ => return,
_ => create_function(p),
};
}
(CREATE_KW, RECURSIVE_KW | VIEW_KW) => {
Expand All @@ -12884,6 +12881,43 @@ fn opt_schema_elements(p: &mut Parser<'_>) {
(CREATE_KW, INDEX_KW | UNIQUE_KW) => {
create_index(p);
}
(CREATE_KW, AGGREGATE_KW) => {
create_aggregate(p);
}
(CREATE_KW, COLLATION_KW) => {
create_collation(p);
}
(CREATE_KW, DOMAIN_KW) => {
create_domain(p);
}
(CREATE_KW, FUNCTION_KW) => {
create_function(p);
}
(CREATE_KW, OPERATOR_KW) => {
match p.nth(2) {
CLASS_KW => create_operator_class(p),
FAMILY_KW => create_operator_family(p),
_ => create_operator(p),
};
}
(CREATE_KW, PROCEDURE_KW) => {
create_procedure(p);
}
(CREATE_KW, TEXT_KW) if p.nth_at(2, SEARCH_KW) => {
match p.nth(3) {
CONFIGURATION_KW => create_text_search_config(p),
DICTIONARY_KW => create_text_search_dict(p),
PARSER_KW => create_text_search_parser(p),
TEMPLATE_KW => create_text_search_template(p),
_ => return,
};
}
(CREATE_KW, TYPE_KW) => {
create_type(p);
}
(GRANT_KW, _) => {
grant(p);
}
_ => return,
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: postgres/regression_suite/compression_pglz.sql
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: postgres/regression_suite/database_ddl.sql
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: postgres/regression_suite/role_ddl.sql
---

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: postgres/regression_suite/tablespace_ddl.sql
---

6 changes: 6 additions & 0 deletions postgres/regression_suite/cluster.sql
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ REPACK clstrpart;
CREATE TEMP TABLE new_cluster_info AS SELECT relname, level, relfilenode, relkind FROM pg_partition_tree('clstrpart'::regclass) AS tree JOIN pg_class c ON c.oid=tree.relid ;
SELECT relname, old.level, old.relkind, old.relfilenode = new.relfilenode FROM old_cluster_info AS old JOIN new_cluster_info AS new USING (relname) ORDER BY relname COLLATE "C";

-- CONCURRENTLY doesn't like partitioned tables
REPACK (CONCURRENTLY) clstrpart;

DROP TABLE clstrpart;

-- Ownership of partitions is checked
Expand Down Expand Up @@ -383,6 +386,9 @@ JOIN relnodes_new n ON o.relname = n.relname
WHERE o.relfilenode <> n.relfilenode
ORDER BY o.relname;

-- concurrently
REPACK (CONCURRENTLY) pg_class;

-- clean up
DROP TABLE clustertest;
DROP TABLE clstr_1;
Expand Down
45 changes: 45 additions & 0 deletions postgres/regression_suite/collate.icu.utf8.sql
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,51 @@ RESET enable_partitionwise_aggregate;
RESET max_parallel_workers_per_gather;
RESET enable_incremental_sort;

--
-- Test for eager aggregation non-deterministic collation bug
--

CREATE TABLE eager_agg_t1 (id int, val text COLLATE case_insensitive);
CREATE TABLE eager_agg_t2 (val text COLLATE case_insensitive);

INSERT INTO eager_agg_t1 SELECT 1, 'a' FROM generate_series(1, 50);
INSERT INTO eager_agg_t1 SELECT 1, 'A' FROM generate_series(1, 50);
INSERT INTO eager_agg_t2 VALUES ('A');

ANALYZE eager_agg_t1;
ANALYZE eager_agg_t2;

-- Ensure that eager aggregation is not used for t1.val due to the
-- non-deterministic collation.
EXPLAIN (COSTS OFF)
SELECT t1.id, count(t1.val)
FROM eager_agg_t1 t1
JOIN eager_agg_t2 t2 ON t1.val = t2.val COLLATE "C"
GROUP BY t1.id;

-- Ensure it returns 1 row with count = 50
SELECT t1.id, count(t1.val)
FROM eager_agg_t1 t1
JOIN eager_agg_t2 t2 ON t1.val = t2.val COLLATE "C"
GROUP BY t1.id;

-- Ensure that eager aggregation is not used when grouping by a column with
-- non-deterministic collation.
EXPLAIN (COSTS OFF)
SELECT t1.id, t1.val, count(t1.val)
FROM eager_agg_t1 t1
JOIN eager_agg_t2 t2 ON t1.val = t2.val COLLATE "C"
GROUP BY t1.id, t1.val;

-- Ensure it returns 1 row with count = 50
SELECT t1.id, t1.val, count(t1.val)
FROM eager_agg_t1 t1
JOIN eager_agg_t2 t2 ON t1.val = t2.val COLLATE "C"
GROUP BY t1.id, t1.val;

DROP TABLE eager_agg_t1;
DROP TABLE eager_agg_t2;

-- virtual generated columns
CREATE TABLE t5 (
a int,
Expand Down
53 changes: 53 additions & 0 deletions postgres/regression_suite/compression_pglz.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
--
-- Tests for PGLZ compression
--

-- directory paths and dlsuffix are passed to us in environment variables
-- \getenv libdir PG_LIBDIR
-- \getenv dlsuffix PG_DLSUFFIX

-- \set regresslib :libdir '/regress' :dlsuffix

CREATE FUNCTION test_pglz_compress(bytea)
RETURNS bytea
AS 'regresslib' LANGUAGE C STRICT;
CREATE FUNCTION test_pglz_decompress(bytea, int4, bool)
RETURNS bytea
AS 'regresslib' LANGUAGE C STRICT;

-- Round-trip with pglz: compress then decompress.
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 400, false) =
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok;
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 400, true) =
decode(repeat('abcd', 100), 'escape') AS roundtrip_ok;

-- Decompression with rawsize too large, fails to fill the destination
-- buffer.
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 500, true);

-- Decompression with rawsize too small, fails with source not fully
-- consumed.
SELECT test_pglz_decompress(test_pglz_compress(
decode(repeat('abcd', 100), 'escape')), 100, true);

-- Corrupted compressed data. Set control bit with read of a match tag,
-- no data follows.
SELECT length(test_pglz_decompress('\x01'::bytea, 1024, false)) AS ctrl_only_len;
SELECT test_pglz_decompress('\x01'::bytea, 1024, true);

-- Corrupted compressed data. Set control bit with read of a match tag,
-- 1 byte follows.
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, false);
SELECT test_pglz_decompress('\x01ff'::bytea, 1024, true);

-- Corrupted compressed data. Set control bit with match tag where length
-- nibble is 3 bytes (extended length), no data follows.
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, false);
SELECT test_pglz_decompress('\x010f01'::bytea, 1024, true);

-- Clean up
DROP FUNCTION test_pglz_compress;
DROP FUNCTION test_pglz_decompress;
27 changes: 0 additions & 27 deletions postgres/regression_suite/conversion.sql
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'iso8859-5')).* fr
-- Test conversions from ISO-8859-5
select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'utf8')).* from iso8859_5_inputs;
select description, inbytes, (test_conv(inbytes, 'iso8859-5', 'koi8r')).* from iso8859_5_inputs;
select description, inbytes, (test_conv(inbytes, 'iso8859_5', 'mule_internal')).* from iso8859_5_inputs;

--
-- Big5
Expand All @@ -346,29 +345,3 @@ insert into big5_inputs values
select description, inbytes, (test_conv(inbytes, 'big5', 'big5')).* from big5_inputs;
-- Test conversions from Big5
select description, inbytes, (test_conv(inbytes, 'big5', 'utf8')).* from big5_inputs;
select description, inbytes, (test_conv(inbytes, 'big5', 'mule_internal')).* from big5_inputs;

--
-- MULE_INTERNAL
--
CREATE TABLE mic_inputs (inbytes bytea, description text);
insert into mic_inputs values
('\x666f6f', 'valid, pure ASCII'),
('\x8bc68bcf8bcf', 'valid (in KOI8R)'),
('\x8bc68bcf8b', 'invalid,incomplete char'),
('\x92bedd', 'valid (in SHIFT_JIS)'),
('\x92be', 'invalid, incomplete char)'),
('\x666f6f95a3c1', 'valid (in Big5)'),
('\x666f6f95a3', 'invalid, incomplete char'),
('\x9200bedd', 'invalid, NUL byte'),
('\x92bedd00', 'invalid, NUL byte'),
('\x8b00c68bcf8bcf', 'invalid, NUL byte');

-- Test MULE_INTERNAL verification
select description, inbytes, (test_conv(inbytes, 'mule_internal', 'mule_internal')).* from mic_inputs;
-- Test conversions from MULE_INTERNAL
select description, inbytes, (test_conv(inbytes, 'mule_internal', 'koi8r')).* from mic_inputs;
select description, inbytes, (test_conv(inbytes, 'mule_internal', 'iso8859-5')).* from mic_inputs;
select description, inbytes, (test_conv(inbytes, 'mule_internal', 'sjis')).* from mic_inputs;
select description, inbytes, (test_conv(inbytes, 'mule_internal', 'big5')).* from mic_inputs;
select description, inbytes, (test_conv(inbytes, 'mule_internal', 'euc_jp')).* from mic_inputs;
2 changes: 2 additions & 0 deletions postgres/regression_suite/copy2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ COPY x from stdin WHERE a IN (generate_series(1,5));
--
COPY x from stdin WHERE a = row_number() over(b);
--
COPY x from stdin WHERE tableoid = 'x'::regclass;
--
--
-- -- check results of copy in
SELECT * FROM x;
Expand Down
Loading
Loading