Found while working on #86 / #90. Pre-existing and independent of --hide-internal-tables — it reproduces with the flag off.
Problem
CREATE_TABLE_REGEX (src/translator/create_table_translator.rs:10-13) is
(?is)CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?(?:"([^"]+)"|(\w+))\s*\((.*)\)
and translate_with_connection rebuilds the statement from capture group 3 alone (:90):
let sqlite_sql = format!("CREATE TABLE {} ({})", table_name_for_output, final_columns);
For a PostgreSQL-style CTAS carrying an explicit column list, group 3 captures only the column definitions and the AS SELECT tail is discarded:
| Input |
Group 3 |
Rebuilt |
CREATE TABLE t (name TEXT) AS SELECT name FROM src |
name TEXT |
CREATE TABLE t (name TEXT) |
CREATE TABLE t AS SELECT name FROM src |
no match |
passed through unchanged (correct) |
So the client gets a success response and an empty table. No error, no warning. The plain CTAS form is unaffected because the regex requires ( right after the table name.
CREATE TABLE t (a, b) AS SELECT ... is valid PostgreSQL, so a PostgreSQL client has every reason to send it.
Reproduction
CREATE TABLE src (name TEXT);
INSERT INTO src VALUES ('alice');
CREATE TABLE snap (name TEXT) AS SELECT name FROM src;
SELECT count(*) FROM snap; -- 0, expected 1
Note for whoever fixes this
tests/sqlite_master_filter_enabled_test.rs has ctas_with_explicit_column_list_never_leaks_internal_prefix, added in #90. Its "no __pgsqlite_ rows" assertion currently passes vacuously in the success branch, because this bug leaves the table empty so there are no rows to inspect. Once this is fixed, that test should be strengthened to assert the expected rows actually land.
Related: #90 works around the interaction by skipping the sqlite_master rewrite when a CTAS carries an explicit column list (src/translator/sqlite_master_filter.rs), because the injected subquery's parens extended the greedy capture into malformed SQL. That guard can be revisited once the regex is fixed.
Found while working on #86 / #90. Pre-existing and independent of
--hide-internal-tables— it reproduces with the flag off.Problem
CREATE_TABLE_REGEX(src/translator/create_table_translator.rs:10-13) isand
translate_with_connectionrebuilds the statement from capture group 3 alone (:90):For a PostgreSQL-style CTAS carrying an explicit column list, group 3 captures only the column definitions and the
AS SELECTtail is discarded:CREATE TABLE t (name TEXT) AS SELECT name FROM srcname TEXTCREATE TABLE t (name TEXT)CREATE TABLE t AS SELECT name FROM srcSo the client gets a success response and an empty table. No error, no warning. The plain CTAS form is unaffected because the regex requires
(right after the table name.CREATE TABLE t (a, b) AS SELECT ...is valid PostgreSQL, so a PostgreSQL client has every reason to send it.Reproduction
Note for whoever fixes this
tests/sqlite_master_filter_enabled_test.rshasctas_with_explicit_column_list_never_leaks_internal_prefix, added in #90. Its "no__pgsqlite_rows" assertion currently passes vacuously in the success branch, because this bug leaves the table empty so there are no rows to inspect. Once this is fixed, that test should be strengthened to assert the expected rows actually land.Related: #90 works around the interaction by skipping the
sqlite_masterrewrite when a CTAS carries an explicit column list (src/translator/sqlite_master_filter.rs), because the injected subquery's parens extended the greedy capture into malformed SQL. That guard can be revisited once the regex is fixed.