Merge branch cassandra-3.0 into cassandra-3.11
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/73547a34 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/73547a34 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/73547a34 Branch: refs/heads/cassandra-3.11 Commit: 73547a3421cc92e07d0373846fc1bff796570275 Parents: 249e4b1 9fc1ffb Author: Benjamin Lerer <b.le...@gmail.com> Authored: Thu Dec 15 18:04:34 2016 +0100 Committer: Benjamin Lerer <b.le...@gmail.com> Committed: Thu Dec 15 18:07:59 2016 +0100 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../restrictions/StatementRestrictions.java | 11 +++ .../cql3/statements/BatchStatement.java | 11 ++- .../cql3/statements/ModificationStatement.java | 10 ++- .../cql3/validation/operations/BatchTest.java | 40 +++++++++++ .../cql3/validation/operations/DeleteTest.java | 57 ++++++++++++++++ .../operations/InsertUpdateIfConditionTest.java | 6 ++ .../cql3/validation/operations/UpdateTest.java | 70 ++++++++++++++++++++ 8 files changed, 194 insertions(+), 12 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/CHANGES.txt ---------------------------------------------------------------------- diff --cc CHANGES.txt index f95dd81,e69bf08..3db0179 --- a/CHANGES.txt +++ b/CHANGES.txt @@@ -1,114 -1,5 +1,115 @@@ -3.0.11 +3.10 + * Remove outboundBindAny configuration property (CASSANDRA-12673) + * Use correct bounds for all-data range when filtering (CASSANDRA-12666) + * Remove timing window in test case (CASSANDRA-12875) + * Resolve unit testing without JCE security libraries installed (CASSANDRA-12945) + * Fix inconsistencies in cassandra-stress load balancing policy (CASSANDRA-12919) + * Fix validation of non-frozen UDT cells (CASSANDRA-12916) + * Don't shut down socket input/output on StreamSession (CASSANDRA-12903) + * Fix Murmur3PartitionerTest (CASSANDRA-12858) + * Move cqlsh syntax rules into separate module and allow easier customization (CASSANDRA-12897) + * Fix CommitLogSegmentManagerTest (CASSANDRA-12283) + * Fix cassandra-stress truncate option (CASSANDRA-12695) + * Fix crossNode value when receiving messages (CASSANDRA-12791) + * Don't load MX4J beans twice (CASSANDRA-12869) + * Extend native protocol request flags, add versions to SUPPORTED, and introduce ProtocolVersion enum (CASSANDRA-12838) + * Set JOINING mode when running pre-join tasks (CASSANDRA-12836) + * remove net.mintern.primitive library due to license issue (CASSANDRA-12845) + * Properly format IPv6 addresses when logging JMX service URL (CASSANDRA-12454) + * Optimize the vnode allocation for single replica per DC (CASSANDRA-12777) + * Use non-token restrictions for bounds when token restrictions are overridden (CASSANDRA-12419) + * Fix CQLSH auto completion for PER PARTITION LIMIT (CASSANDRA-12803) + * Use different build directories for Eclipse and Ant (CASSANDRA-12466) + * Avoid potential AttributeError in cqlsh due to no table metadata (CASSANDRA-12815) + * Fix RandomReplicationAwareTokenAllocatorTest.testExistingCluster (CASSANDRA-12812) + * Upgrade commons-codec to 1.9 (CASSANDRA-12790) + * Make the fanout size for LeveledCompactionStrategy to be configurable (CASSANDRA-11550) + * Add duration data type (CASSANDRA-11873) + * Fix timeout in ReplicationAwareTokenAllocatorTest (CASSANDRA-12784) + * Improve sum aggregate functions (CASSANDRA-12417) + * Make cassandra.yaml docs for batch_size_*_threshold_in_kb reflect changes in CASSANDRA-10876 (CASSANDRA-12761) + * cqlsh fails to format collections when using aliases (CASSANDRA-11534) + * Check for hash conflicts in prepared statements (CASSANDRA-12733) + * Exit query parsing upon first error (CASSANDRA-12598) + * Fix cassandra-stress to use single seed in UUID generation (CASSANDRA-12729) + * CQLSSTableWriter does not allow Update statement (CASSANDRA-12450) + * Config class uses boxed types but DD exposes primitive types (CASSANDRA-12199) + * Add pre- and post-shutdown hooks to Storage Service (CASSANDRA-12461) + * Add hint delivery metrics (CASSANDRA-12693) + * Remove IndexInfo cache from FileIndexInfoRetriever (CASSANDRA-12731) + * ColumnIndex does not reuse buffer (CASSANDRA-12502) + * cdc column addition still breaks schema migration tasks (CASSANDRA-12697) + * Upgrade metrics-reporter dependencies (CASSANDRA-12089) + * Tune compaction thread count via nodetool (CASSANDRA-12248) + * Add +=/-= shortcut syntax for update queries (CASSANDRA-12232) + * Include repair session IDs in repair start message (CASSANDRA-12532) + * Add a blocking task to Index, run before joining the ring (CASSANDRA-12039) + * Fix NPE when using CQLSSTableWriter (CASSANDRA-12667) + * Support optional backpressure strategies at the coordinator (CASSANDRA-9318) + * Make randompartitioner work with new vnode allocation (CASSANDRA-12647) + * Fix cassandra-stress graphing (CASSANDRA-12237) + * Allow filtering on partition key columns for queries without secondary indexes (CASSANDRA-11031) + * Fix Cassandra Stress reporting thread model and precision (CASSANDRA-12585) + * Add JMH benchmarks.jar (CASSANDRA-12586) + * Cleanup uses of AlterTableStatementColumn (CASSANDRA-12567) + * Add keep-alive to streaming (CASSANDRA-11841) + * Tracing payload is passed through newSession(..) (CASSANDRA-11706) + * avoid deleting non existing sstable files and improve related log messages (CASSANDRA-12261) + * json/yaml output format for nodetool compactionhistory (CASSANDRA-12486) + * Retry all internode messages once after a connection is + closed and reopened (CASSANDRA-12192) + * Add support to rebuild from targeted replica (CASSANDRA-9875) + * Add sequence distribution type to cassandra stress (CASSANDRA-12490) + * "SELECT * FROM foo LIMIT ;" does not error out (CASSANDRA-12154) + * Define executeLocally() at the ReadQuery Level (CASSANDRA-12474) + * Extend read/write failure messages with a map of replica addresses + to error codes in the v5 native protocol (CASSANDRA-12311) + * Fix rebuild of SASI indexes with existing index files (CASSANDRA-12374) + * Let DatabaseDescriptor not implicitly startup services (CASSANDRA-9054, 12550) + * Fix clustering indexes in presence of static columns in SASI (CASSANDRA-12378) + * Fix queries on columns with reversed type on SASI indexes (CASSANDRA-12223) + * Added slow query log (CASSANDRA-12403) + * Count full coordinated request against timeout (CASSANDRA-12256) + * Allow TTL with null value on insert and update (CASSANDRA-12216) + * Make decommission operation resumable (CASSANDRA-12008) + * Add support to one-way targeted repair (CASSANDRA-9876) + * Remove clientutil jar (CASSANDRA-11635) + * Fix compaction throughput throttle (CASSANDRA-12366, CASSANDRA-12717) + * Delay releasing Memtable memory on flush until PostFlush has finished running (CASSANDRA-12358) + * Cassandra stress should dump all setting on startup (CASSANDRA-11914) + * Make it possible to compact a given token range (CASSANDRA-10643) + * Allow updating DynamicEndpointSnitch properties via JMX (CASSANDRA-12179) + * Collect metrics on queries by consistency level (CASSANDRA-7384) + * Add support for GROUP BY to SELECT statement (CASSANDRA-10707) + * Deprecate memtable_cleanup_threshold and update default for memtable_flush_writers (CASSANDRA-12228) + * Upgrade to OHC 0.4.4 (CASSANDRA-12133) + * Add version command to cassandra-stress (CASSANDRA-12258) + * Create compaction-stress tool (CASSANDRA-11844) + * Garbage-collecting compaction operation and schema option (CASSANDRA-7019) + * Add beta protocol flag for v5 native protocol (CASSANDRA-12142) + * Support filtering on non-PRIMARY KEY columns in the CREATE + MATERIALIZED VIEW statement's WHERE clause (CASSANDRA-10368) + * Unify STDOUT and SYSTEMLOG logback format (CASSANDRA-12004) + * COPY FROM should raise error for non-existing input files (CASSANDRA-12174) + * Faster write path (CASSANDRA-12269) + * Option to leave omitted columns in INSERT JSON unset (CASSANDRA-11424) + * Support json/yaml output in nodetool tpstats (CASSANDRA-12035) + * Expose metrics for successful/failed authentication attempts (CASSANDRA-10635) + * Prepend snapshot name with "truncated" or "dropped" when a snapshot + is taken before truncating or dropping a table (CASSANDRA-12178) + * Optimize RestrictionSet (CASSANDRA-12153) + * cqlsh does not automatically downgrade CQL version (CASSANDRA-12150) + * Omit (de)serialization of state variable in UDAs (CASSANDRA-9613) + * Create a system table to expose prepared statements (CASSANDRA-8831) + * Reuse DataOutputBuffer from ColumnIndex (CASSANDRA-11970) + * Remove DatabaseDescriptor dependency from SegmentedFile (CASSANDRA-11580) + * Add supplied username to authentication error messages (CASSANDRA-12076) + * Remove pre-startup check for open JMX port (CASSANDRA-12074) + * Remove compaction Severity from DynamicEndpointSnitch (CASSANDRA-11738) + * Restore resumable hints delivery (CASSANDRA-11960) + * Properly report LWT contention (CASSANDRA-12626) +Merged from 3.0: + * Fix DELETE and UPDATE queries with empty IN restrictions (CASSANDRA-12829) * Mark MVs as built after successful bootstrap (CASSANDRA-12984) * Estimated TS drop-time histogram updated with Cell.NO_DELETION_TIME (CASSANDRA-13040) * Nodetool compactionstats fails with NullPointerException (CASSANDRA-13021) http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java index 2d04633,542dec9..6b89579 --- a/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java +++ b/src/java/org/apache/cassandra/cql3/restrictions/StatementRestrictions.java @@@ -471,6 -430,17 +471,17 @@@ public final class StatementRestriction } /** + * Checks if restrictions on the clustering key have IN restrictions. + * + * @return <code>true</code> if the restrictions on the clustering key have IN restrictions, + * <code>false</code> otherwise. + */ + public boolean clusteringKeyRestrictionsHasIN() + { - return clusteringColumnsRestrictions.isIN(); ++ return clusteringColumnsRestrictions.hasIN(); + } + + /** * Processes the clustering column restrictions. * * @param hasQueriableIndex <code>true</code> if some of the queried data are indexed, <code>false</code> otherwise http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java ---------------------------------------------------------------------- diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java index 118a1e2,18a6ca3..62a7954 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/DeleteTest.java @@@ -1244,4 -1164,87 +1244,61 @@@ public class DeleteTest extends CQLTest row(bytes("foo123"), bytes("1"), bytes("2"), bytes("3"))); } } + - @Test - public void testDeleteAndReverseQueries() throws Throwable - { - // This test insert rows in one sstable and a range tombstone covering some of those rows in another, and it - // validates we correctly get only the non-removed rows when doing reverse queries. - - createTable("CREATE TABLE %s (k text, i int, PRIMARY KEY (k, i))"); - - for (int i = 0; i < 10; i++) - execute("INSERT INTO %s(k, i) values (?, ?)", "a", i); - - flush(); - - execute("DELETE FROM %s WHERE k = ? AND i >= ? AND i <= ?", "a", 2, 7); - - assertRows(execute("SELECT i FROM %s WHERE k = ? ORDER BY i DESC", "a"), - row(9), row(8), row(1), row(0) - ); - - flush(); - - assertRows(execute("SELECT i FROM %s WHERE k = ? ORDER BY i DESC", "a"), - row(9), row(8), row(1), row(0) - ); - } - + /** + * Test for CASSANDRA-12829 + */ + @Test + public void testDeleteWithEmptyInRestriction() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))"); + execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 1, 1); + execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 2, 2); + execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)", 1, 3, 3); + + execute("DELETE FROM %s WHERE a IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b = 1;"); + execute("DELETE FROM %s WHERE a = 1 AND b IN ();"); + assertRows(execute("SELECT * FROM %s"), + row(1, 1, 1), + row(1, 2, 2), + row(1, 3, 3)); + + createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))"); + execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 1, 1, 1); + execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 2, 2, 1); + execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)", 1, 1, 3, 3, 1); + + execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN ();"); + execute("DELETE FROM %s WHERE a = 1 AND b IN () AND c IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b = 1 AND c IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1;"); + assertRows(execute("SELECT * FROM %s"), + row(1, 1, 1, 1, 1), + row(1, 1, 2, 1, 2), + row(1, 1, 3, 1, 3)); + + createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))"); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 1, 1); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 2, 2); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 3, 3); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)", 1, 1, 1, 4, 4); + + execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN ();"); + execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c = 1 AND d IN ();"); + execute("DELETE FROM %s WHERE a = 1 AND b = 1 AND c IN () AND d IN ();"); + execute("DELETE FROM %s WHERE a = 1 AND b IN () AND c IN () AND d IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN () AND d IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b IN () AND c IN () AND d = 1;"); + execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1 AND d = 1;"); + execute("DELETE FROM %s WHERE a IN () AND b IN () AND c = 1 AND d IN ();"); + execute("DELETE FROM %s WHERE a IN () AND b = 1"); + assertRows(execute("SELECT * FROM %s"), + row(1, 1, 1, 1, 1), + row(1, 1, 1, 2, 2), + row(1, 1, 1, 3, 3), + row(1, 1, 1, 4, 4)); + } } http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/73547a34/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java ---------------------------------------------------------------------- diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java index 494abaa,690d4f9..51280a9 --- a/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java +++ b/test/unit/org/apache/cassandra/cql3/validation/operations/UpdateTest.java @@@ -526,59 -521,72 +526,129 @@@ public class UpdateTest extends CQLTest assertRows(execute("SELECT l FROM %s WHERE k = 0"), row(list("v1", "v4", "v3"))); } + @Test + public void testUpdateWithDefaultTtl() throws Throwable + { + final int secondsPerMinute = 60; + createTable("CREATE TABLE %s (a int PRIMARY KEY, b int) WITH default_time_to_live = " + (10 * secondsPerMinute)); + + execute("UPDATE %s SET b = 1 WHERE a = 1"); + UntypedResultSet resultSet = execute("SELECT ttl(b) FROM %s WHERE a = 1"); + Assert.assertEquals(1, resultSet.size()); + Row row = resultSet.one(); + Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute)); + + execute("UPDATE %s USING TTL ? SET b = 3 WHERE a = 1", 0); + assertRows(execute("SELECT ttl(b) FROM %s WHERE a = 1"), row(new Object[]{null})); + + execute("UPDATE %s SET b = 3 WHERE a = 1"); + resultSet = execute("SELECT ttl(b) FROM %s WHERE a = 1"); + Assert.assertEquals(1, resultSet.size()); + row = resultSet.one(); + Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute)); + + execute("UPDATE %s USING TTL ? SET b = 2 WHERE a = 2", unset()); + resultSet = execute("SELECT ttl(b) FROM %s WHERE a = 2"); + Assert.assertEquals(1, resultSet.size()); + row = resultSet.one(); + Assert.assertTrue(row.getInt("ttl(b)") >= (9 * secondsPerMinute)); + + execute("UPDATE %s USING TTL ? SET b = ? WHERE a = ?", null, 3, 3); + assertRows(execute("SELECT ttl(b) FROM %s WHERE a = 3"), row(new Object[] { null })); + } + + @Test + public void testUpdateWithTtl() throws Throwable + { + createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)"); + + execute("INSERT INTO %s (k, v) VALUES (1, 1) USING TTL ?", 3600); + execute("INSERT INTO %s (k, v) VALUES (2, 2) USING TTL ?", 3600); + + // test with unset + execute("UPDATE %s USING TTL ? SET v = ? WHERE k = ?", unset(), 1, 1); // treat as 'unlimited' + assertRows(execute("SELECT ttl(v) FROM %s WHERE k = 1"), row(new Object[] { null })); + + // test with null + execute("UPDATE %s USING TTL ? SET v = ? WHERE k = ?", unset(), 2, 2); + assertRows(execute("SELECT k, v, TTL(v) FROM %s WHERE k = 2"), row(2, 2, null)); + + // test error handling + assertInvalidMessage("A TTL must be greater or equal to 0, but was -5", + "UPDATE %s USING TTL ? SET v = ? WHERE k = ?", -5, 1, 1); + + assertInvalidMessage("ttl is too large.", + "UPDATE %s USING TTL ? SET v = ? WHERE k = ?", + Attributes.MAX_TTL + 1, 1, 1); + } ++ + /** + * Test for CASSANDRA-12829 + */ + @Test + public void testUpdateWithEmptyInRestriction() throws Throwable + { + createTable("CREATE TABLE %s (a int, b int, c int, PRIMARY KEY (a,b))"); + execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,1,1); + execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,2,2); + execute("INSERT INTO %s (a,b,c) VALUES (?,?,?)",1,3,3); + + assertInvalidMessage("Some clustering keys are missing: b", + "UPDATE %s SET c = 100 WHERE a IN ();"); + execute("UPDATE %s SET c = 100 WHERE a IN () AND b IN ();"); + execute("UPDATE %s SET c = 100 WHERE a IN () AND b = 1;"); + execute("UPDATE %s SET c = 100 WHERE a = 1 AND b IN ();"); + assertRows(execute("SELECT * FROM %s"), + row(1,1,1), + row(1,2,2), + row(1,3,3)); + + createTable("CREATE TABLE %s (a int, b int, c int, d int, s int static, PRIMARY KEY ((a,b), c))"); + execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,1,1,1); + execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,2,2,1); + execute("INSERT INTO %s (a,b,c,d,s) VALUES (?,?,?,?,?)",1,1,3,3,1); + + execute("UPDATE %s SET d = 100 WHERE a = 1 AND b = 1 AND c IN ();"); + execute("UPDATE %s SET d = 100 WHERE a = 1 AND b IN () AND c IN ();"); + execute("UPDATE %s SET d = 100 WHERE a IN () AND b IN () AND c IN ();"); + execute("UPDATE %s SET d = 100 WHERE a IN () AND b IN () AND c = 1;"); + execute("UPDATE %s SET d = 100 WHERE a IN () AND b = 1 AND c IN ();"); + assertRows(execute("SELECT * FROM %s"), + row(1,1,1,1,1), + row(1,1,2,1,2), + row(1,1,3,1,3)); + + // No clustering keys restricted, update whole partition + execute("UPDATE %s set s = 100 where a = 1 AND b = 1;"); + assertRows(execute("SELECT * FROM %s"), + row(1,1,1,100,1), + row(1,1,2,100,2), + row(1,1,3,100,3)); + + execute("UPDATE %s set s = 200 where a = 1 AND b IN ();"); + assertRows(execute("SELECT * FROM %s"), + row(1,1,1,100,1), + row(1,1,2,100,2), + row(1,1,3,100,3)); + + createTable("CREATE TABLE %s (a int, b int, c int, d int, e int, PRIMARY KEY ((a,b), c, d))"); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,1,1); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,2,2); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,3,3); + execute("INSERT INTO %s (a,b,c,d,e) VALUES (?,?,?,?,?)",1,1,1,4,4); + + execute("UPDATE %s SET e = 100 WHERE a = 1 AND b = 1 AND c = 1 AND d IN ();"); + execute("UPDATE %s SET e = 100 WHERE a = 1 AND b = 1 AND c IN () AND d IN ();"); + execute("UPDATE %s SET e = 100 WHERE a = 1 AND b IN () AND c IN () AND d IN ();"); + execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c IN () AND d IN ();"); + execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c IN () AND d = 1;"); + execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c = 1 AND d = 1;"); + execute("UPDATE %s SET e = 100 WHERE a IN () AND b IN () AND c = 1 AND d IN ();"); + assertRows(execute("SELECT * FROM %s"), + row(1,1,1,1,1), + row(1,1,1,2,2), + row(1,1,1,3,3), + row(1,1,1,4,4)); + } ++ }