You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Refuse a grid save that would send an UPDATE or DELETE without a WHERE #3664
A grid save must never send an UPDATE or DELETE that can reach rows the user did not edit. TablePro's own generator refuses to build one without a WHERE (apple/TablePro/Core/ChangeTracking/SQLStatementGenerator.swift:362 and :392 for UPDATE, :447 for DELETE), and tests cover it (SQLStatementGeneratorNoPKTests.swift:33, SQLStatementGeneratorTests.swift). Drivers that write their own statements are not covered the same way:
12 plugins implement generateStatements: BigQuery, ClickHouse, Dameng, DynamoDB, Kafka, SQL Server, Oracle, Snowflake, Spanner, Teradata, Trino and Weaviate. Only ClickHouse has a test target (apple/Plugins/ClickHouseDriverTests). MSSQLStatementGenerator (apple/Plugins/MSSQLDriverPlugin/MSSQLStatementGenerator.swift) and the Oracle row writer have no test.
The host adopts a plugin's statements as written (apple/TablePro/Core/DataWrite/RowChangeStatementFactory.swift:418). It holds one to a row count only on a table with no primary key, and only where the engine's count is real (RowChangeStatementFactory.swift:455). Nothing checks that an UPDATE or DELETE from a plugin carries a WHERE.
ENUM and SET values are parsed in tests (apple/TableProTests/Core/Services/ColumnTypeTests.swift:181), but no test or probe saves an ENUM or SET edit to MySQL and reads it back.
Proposed solution
Before a save sends anything, check every UPDATE and DELETE a plugin returned for a SQL dialect: one with no WHERE clause stops the save, names the table and keeps the queue, the way an unwritable change does today (features/change-tracking.mdx).
Tests that feed that check a statement with no WHERE, a WHERE in a comment, and a WHERE inside a string literal.
Tests for each SQL plugin generator that an update and a delete on a table with a primary key, and on one without, carry a WHERE that names the row. Move a generator into a package with a test target where its plugin has none.
A probe under apple/scripts/probes/ that edits ENUM and SET cells on MySQL and MariaDB through the grid's save path and reads the values back: a single value, several SET members, an empty SET, NULL, and a value with a quote.
Done when no SQL driver can send an UPDATE or DELETE without a WHERE from a grid save, a test fails if one tries, and the ENUM and SET probe passes on both servers.
Activity