This is an automated email from the ASF dual-hosted git repository. aweisberg pushed a commit to branch cas-accord-v2 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit d4a8b5b39fd3f655eb2f6a6f0638f849cadd5494 Author: Caleb Rackliffe <calebrackli...@gmail.com> AuthorDate: Tue Dec 6 17:10:04 2022 -0600 removing TxnBuilder-based tests from TransactionStatementTest --- src/java/org/apache/cassandra/cql3/Constants.java | 2 + .../cql3/transactions/ReferenceOperation.java | 1 + .../cql3/statements/TransactionStatementTest.java | 295 --------------------- .../cassandra/service/accord/txn/TxnBuilder.java | 2 +- 4 files changed, 4 insertions(+), 296 deletions(-) diff --git a/src/java/org/apache/cassandra/cql3/Constants.java b/src/java/org/apache/cassandra/cql3/Constants.java index 0badfd967e..5bdbe823f4 100644 --- a/src/java/org/apache/cassandra/cql3/Constants.java +++ b/src/java/org/apache/cassandra/cql3/Constants.java @@ -490,6 +490,8 @@ public abstract class Constants { @SuppressWarnings("unchecked") NumberType<Number> type = (NumberType<Number>) column.type; ByteBuffer increment = t.bindAndGet(params.options); + if (increment == null) + throw new InvalidRequestException("Invalid null value for number increment"); ByteBuffer current = getCurrentCellBuffer(partitionKey, params); if (current == null) return; diff --git a/src/java/org/apache/cassandra/cql3/transactions/ReferenceOperation.java b/src/java/org/apache/cassandra/cql3/transactions/ReferenceOperation.java index 5f25ada796..c944fdd132 100644 --- a/src/java/org/apache/cassandra/cql3/transactions/ReferenceOperation.java +++ b/src/java/org/apache/cassandra/cql3/transactions/ReferenceOperation.java @@ -70,6 +70,7 @@ public class ReferenceOperation ColumnMetadata receiver = operation.column; ReferenceValue value = new ReferenceValue.Constant(operation.term()); + // TODO: Receiver might need to be modified here, just as we do in Raw#prepare() Term key = extractKeyOrIndex(operation); FieldIdentifier field = extractField(operation); return new ReferenceOperation(receiver, kind, key, field, value); diff --git a/test/unit/org/apache/cassandra/cql3/statements/TransactionStatementTest.java b/test/unit/org/apache/cassandra/cql3/statements/TransactionStatementTest.java index 492e3e67a2..d83cb0ae44 100644 --- a/test/unit/org/apache/cassandra/cql3/statements/TransactionStatementTest.java +++ b/test/unit/org/apache/cassandra/cql3/statements/TransactionStatementTest.java @@ -18,47 +18,17 @@ package org.apache.cassandra.cql3.statements; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import com.google.common.collect.ImmutableList; - -import org.apache.cassandra.service.accord.txn.*; import org.assertj.core.api.Assertions; import org.junit.BeforeClass; import org.junit.Test; -import accord.primitives.Txn; import org.apache.cassandra.SchemaLoader; -import org.apache.cassandra.cql3.ColumnIdentifier; -import org.apache.cassandra.cql3.QueryOptions; import org.apache.cassandra.cql3.QueryProcessor; -import org.apache.cassandra.cql3.VariableSpecifications; -import org.apache.cassandra.db.BufferClustering; -import org.apache.cassandra.db.Clustering; -import org.apache.cassandra.db.Columns; -import org.apache.cassandra.db.DecoratedKey; -import org.apache.cassandra.db.LivenessInfo; -import org.apache.cassandra.db.RegularAndStaticColumns; -import org.apache.cassandra.db.marshal.Int32Type; -import org.apache.cassandra.db.marshal.ListType; -import org.apache.cassandra.db.partitions.PartitionUpdate; -import org.apache.cassandra.db.rows.BTreeRow; -import org.apache.cassandra.db.rows.Row; import org.apache.cassandra.exceptions.InvalidRequestException; import org.apache.cassandra.exceptions.SyntaxException; -import org.apache.cassandra.schema.ColumnMetadata; import org.apache.cassandra.schema.KeyspaceParams; -import org.apache.cassandra.schema.Schema; import org.apache.cassandra.schema.TableId; -import org.apache.cassandra.schema.TableMetadata; import org.apache.cassandra.service.ClientState; -import org.apache.cassandra.service.accord.txn.TxnReferenceValue.Substitution; - -import static org.junit.Assert.assertEquals; import static org.apache.cassandra.cql3.statements.TransactionStatement.DUPLICATE_TUPLE_NAME_MESSAGE; import static org.apache.cassandra.cql3.statements.TransactionStatement.EMPTY_TRANSACTION_MESSAGE; @@ -67,13 +37,11 @@ import static org.apache.cassandra.cql3.statements.TransactionStatement.INCOMPLE import static org.apache.cassandra.cql3.statements.TransactionStatement.NO_CONDITIONS_IN_UPDATES_MESSAGE; import static org.apache.cassandra.cql3.statements.TransactionStatement.NO_TIMESTAMPS_IN_UPDATES_MESSAGE; import static org.apache.cassandra.cql3.statements.TransactionStatement.SELECT_REFS_NEED_COLUMN_MESSAGE; -import static org.apache.cassandra.service.accord.txn.TxnDataName.user; import static org.apache.cassandra.cql3.statements.UpdateStatement.UPDATING_PRIMARY_KEY_MESSAGE; import static org.apache.cassandra.cql3.statements.schema.CreateTableStatement.parse; import static org.apache.cassandra.cql3.transactions.RowDataReference.CANNOT_FIND_TUPLE_MESSAGE; import static org.apache.cassandra.cql3.transactions.RowDataReference.COLUMN_NOT_IN_TUPLE_MESSAGE; import static org.apache.cassandra.schema.TableMetadata.UNDEFINED_COLUMN_NAME_MESSAGE; -import static org.apache.cassandra.utils.ByteBufferUtil.bytes; public class TransactionStatementTest { @@ -82,11 +50,6 @@ public class TransactionStatementTest private static final TableId TABLE3_ID = TableId.fromString("00000000-0000-0000-0000-000000000003"); private static final TableId TABLE4_ID = TableId.fromString("00000000-0000-0000-0000-000000000004"); - private static TableMetadata TABLE1; - private static TableMetadata TABLE2; - private static TableMetadata TABLE3; - private static TableMetadata TABLE4; - @BeforeClass public static void beforeClass() throws Exception { @@ -96,11 +59,6 @@ public class TransactionStatementTest parse("CREATE TABLE tbl2 (k int, c int, v int, primary key (k, c))", "ks").id(TABLE2_ID), parse("CREATE TABLE tbl3 (k int PRIMARY KEY, \"with spaces\" int, \"with\"\"quote\" int, \"MiXeD_CaSe\" int)", "ks").id(TABLE3_ID), parse("CREATE TABLE tbl4 (k int PRIMARY KEY, int_list list<int>)", "ks").id(TABLE4_ID)); - - TABLE1 = Schema.instance.getTableMetadata("ks", "tbl1"); - TABLE2 = Schema.instance.getTableMetadata("ks", "tbl2"); - TABLE3 = Schema.instance.getTableMetadata("ks", "tbl3"); - TABLE4 = Schema.instance.getTableMetadata("ks", "tbl4"); } @Test @@ -359,257 +317,4 @@ public class TransactionStatementTest .isInstanceOf(InvalidRequestException.class) .hasMessageContaining(String.format(COLUMN_NOT_IN_TUPLE_MESSAGE, "q", "row1")); } - - @Test - public void simpleQueryTest() - { - String query = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl1 WHERE k=1 AND c=?);\n" + - " LET row2 = (SELECT * FROM ks.tbl2 WHERE k=2 AND c=2);\n" + - " SELECT v FROM ks.tbl1 WHERE k=2 AND c=?;\n" + - " IF row1 IS NOT NULL AND row1.v = 3 AND row2.v=? THEN\n" + - " UPDATE ks.tbl1 SET v=? WHERE k=1 AND c=2;\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl1 WHERE k=1 AND c=2") - .withRead("row2", "SELECT * FROM ks.tbl2 WHERE k=2 AND c=2") - .withRead(TxnDataName.returning(), "SELECT v FROM ks.tbl1 WHERE k=2 AND c=2") - .withWrite("UPDATE ks.tbl1 SET v=1 WHERE k=1 AND c=2") - .withIsNotNullCondition(user("row1"), null) - .withEqualsCondition("row1", "v", bytes(3)) - .withEqualsCondition("row2", "v", bytes(4)) - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(query); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - List<ByteBuffer> values = ImmutableList.of(bytes(2), bytes(2), bytes(4), bytes(1)); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.forInternalCalls(values)); - - assertEquals(expected, actual); - } - - @Test - public void txnWithReturningStatement() - { - String query = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl1 WHERE k=1 AND c=2);\n" + - " LET row2 = (SELECT * FROM ks.tbl2 WHERE k=2 AND c=2);\n" + - " SELECT row1.v, row2.v;\n" + - " IF row1 IS NOT NULL AND row1.v = 3 AND row2.v=4 THEN\n" + - " UPDATE ks.tbl1 SET v=1 WHERE k=1 AND c=2;\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl1 WHERE k=1 AND c=2") - .withRead("row2", "SELECT * FROM ks.tbl2 WHERE k=2 AND c=2") - .withWrite("UPDATE ks.tbl1 SET v=1 WHERE k=1 AND c=2") - .withIsNotNullCondition(user("row1"), null) - .withEqualsCondition("row1", "v", bytes(3)) - .withEqualsCondition("row2", "v", bytes(4)) - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(query); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.DEFAULT); - - assertEquals(expected, actual); - assertEquals(2, statement.getReturningReferences().size()); - } - - @Test - public void testQuotedColumnNames() - { - String query = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl3 WHERE k=1);\n" + - " SELECT \"row1\".\"with spaces\", row1.\"with\"\"quote\", row1.\"MiXeD_CaSe\";\n" + - " IF row1.\"with spaces\" IS NULL THEN\n" + - " INSERT INTO ks.tbl3 (k, \"with spaces\") VALUES (1, 2);\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl3 WHERE k=1") - .withWrite("INSERT INTO ks.tbl3 (k, \"with spaces\") VALUES (1, 2)") - .withIsNullCondition(user("row1"), "with spaces") - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(query); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.DEFAULT); - - assertEquals(expected, actual); - assertEquals(3, statement.getReturningReferences().size()); - assertEquals("with spaces", statement.getReturningReferences().get(0).column().name.toString()); - assertEquals("with\"quote", statement.getReturningReferences().get(1).column().name.toString()); - assertEquals("MiXeD_CaSe", statement.getReturningReferences().get(2).column().name.toString()); - } - - @Test - public void updateVariableSubstitutionTest() - { - String query = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl1 WHERE k=1 AND c=2);\n" + - " LET row2 = (SELECT * FROM ks.tbl2 WHERE k=2 AND c=2);\n" + - " SELECT v FROM ks.tbl1 WHERE k=1 AND c=2;\n" + - " IF row1.v = 3 AND row2.v=4 THEN\n" + - " UPDATE ks.tbl1 SET v = row2.v WHERE k=1 AND c=2;\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - List<TxnReferenceOperation> regularOps = new ArrayList<>(); - regularOps.add(new TxnReferenceOperation(TxnReferenceOperation.Kind.ConstantSetter, column(TABLE1, "v"), null, null, new Substitution(reference(user("row2"), TABLE2, "v")))); - TxnReferenceOperations referenceOps = new TxnReferenceOperations(TABLE1, Clustering.make(bytes(2)), regularOps, Collections.emptyList()); - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl1 WHERE k=1 AND c=2") - .withRead("row2", "SELECT * FROM ks.tbl2 WHERE k=2 AND c=2") - .withRead(TxnDataName.returning(), "SELECT v FROM ks.tbl1 WHERE k=1 AND c=2") - .withWrite(emptyUpdate(TABLE1, 1, 2, false), referenceOps) - .withEqualsCondition("row1", "v", bytes(3)) - .withEqualsCondition("row2", "v", bytes(4)) - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(query); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.DEFAULT); - assertEquals(expected, actual); - } - - @Test - public void insertVariableSubstitutionTest() - { - String query = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl1 WHERE k=1 AND c=2);\n" + - " LET row2 = (SELECT * FROM ks.tbl2 WHERE k=2 AND c=2);\n" + - " SELECT v FROM ks.tbl1 WHERE k=1 AND c=2;\n" + - " IF row1.v = 3 AND row2.v=4 THEN\n" + - " INSERT INTO ks.tbl1 (k, c, v) VALUES (1, 2, row2.v);\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - List<TxnReferenceOperation> regularOps = new ArrayList<>(); - regularOps.add(new TxnReferenceOperation(TxnReferenceOperation.Kind.ConstantSetter, column(TABLE1, "v"), null, null, new Substitution(reference(user("row2"), TABLE2, "v")))); - TxnReferenceOperations referenceOps = new TxnReferenceOperations(TABLE1, Clustering.make(bytes(2)), regularOps, Collections.emptyList()); - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl1 WHERE k=1 AND c=2") - .withRead("row2", "SELECT * FROM ks.tbl2 WHERE k=2 AND c=2") - .withRead(TxnDataName.returning(), "SELECT v FROM ks.tbl1 WHERE k=1 AND c=2") - .withWrite(emptyUpdate(TABLE1, 1, 2, true), referenceOps) - .withEqualsCondition("row1", "v", bytes(3)) - .withEqualsCondition("row2", "v", bytes(4)) - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(query); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.DEFAULT); - assertEquals(expected, actual); - } - - @Test - public void testListCondition() - { - String update = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl4 WHERE k = ?);\n" + - " SELECT row1.int_list;\n" + - " IF row1.int_list = ? THEN\n" + - " UPDATE ks.tbl4 SET int_list = ? WHERE k = ?;\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - ListType<Integer> listType = ListType.getInstance(Int32Type.instance, true); - List<Integer> initialList = Arrays.asList(1, 2); - ByteBuffer initialListBytes = listType.getSerializer().serialize(initialList); - - List<Integer> updatedList = Arrays.asList(1, 2, 3); - ByteBuffer updatedListBytes = listType.getSerializer().serialize(updatedList); - - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl4 WHERE k = 0") - .withWrite("UPDATE ks.tbl4 SET int_list = ? WHERE k = 0", - TxnReferenceOperations.empty(), - new VariableSpecifications(Collections.singletonList(null)), - updatedListBytes) - .withEqualsCondition("row1", "int_list", initialListBytes) - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(update); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - - List<ByteBuffer> values = ImmutableList.of(bytes(0), initialListBytes, updatedListBytes, bytes(0)); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.forInternalCalls(values)); - - // TODO: Find a better way to test, given list paths are randomly generated and therefore not comparable. - assertEquals(expected.toString().length(), actual.toString().length()); - - assertEquals(1, statement.getReturningReferences().size()); - assertEquals("int_list", statement.getReturningReferences().get(0).column().name.toString()); - } - - @Test - public void testListSubstitution() - { - String update = "BEGIN TRANSACTION\n" + - " LET row1 = (SELECT * FROM ks.tbl4 WHERE k = ?);\n" + - " SELECT row1.int_list;\n" + - " IF row1.int_list = [1, 2] THEN\n" + - " UPDATE ks.tbl4 SET int_list = row1.int_list WHERE k = ?;\n" + - " END IF\n" + - "COMMIT TRANSACTION"; - - ListType<Integer> listType = ListType.getInstance(Int32Type.instance, true); - List<Integer> initialList = Arrays.asList(1, 2); - ByteBuffer initialListBytes = listType.getSerializer().serialize(initialList); - - List<TxnReferenceOperation> partitionOps = new ArrayList<>(); - partitionOps.add(new TxnReferenceOperation(TxnReferenceOperation.Kind.ListSetter, column(TABLE4, "int_list"), null, null, new Substitution(reference(user("row1"), TABLE4, "int_list")))); - TxnReferenceOperations referenceOps = new TxnReferenceOperations(TABLE4, Clustering.EMPTY, partitionOps, Collections.emptyList()); - - Txn expected = TxnBuilder.builder() - .withRead("row1", "SELECT * FROM ks.tbl4 WHERE k = 0") - .withWrite(emptyUpdate(TABLE4, 1, Clustering.EMPTY, false), referenceOps) - .withEqualsCondition("row1", "int_list", initialListBytes) - .build(); - - TransactionStatement.Parsed parsed = (TransactionStatement.Parsed) QueryProcessor.parseStatement(update); - TransactionStatement statement = (TransactionStatement) parsed.prepare(ClientState.forInternalCalls()); - - List<ByteBuffer> values = ImmutableList.of(bytes(0), bytes(1)); - Txn actual = statement.createTxn(ClientState.forInternalCalls(), QueryOptions.forInternalCalls(values)); - - assertEquals(expected, actual); - assertEquals(1, statement.getReturningReferences().size()); - assertEquals("int_list", statement.getReturningReferences().get(0).column().name.toString()); - } - - private static PartitionUpdate emptyUpdate(TableMetadata metadata, int k, int c, boolean forInsert) - { - return emptyUpdate(metadata, k, new BufferClustering(bytes(c)), forInsert); - } - - private static PartitionUpdate emptyUpdate(TableMetadata metadata, int k, Clustering<?> c, boolean forInsert) - { - DecoratedKey dk = metadata.partitioner.decorateKey(bytes(k)); - RegularAndStaticColumns columns = new RegularAndStaticColumns(Columns.from(metadata.regularColumns()), Columns.NONE); - PartitionUpdate.Builder builder = new PartitionUpdate.Builder(metadata, dk, columns, 1); - - Row.Builder row = BTreeRow.unsortedBuilder(); - row.newRow(c); - if (forInsert) - row.addPrimaryKeyLivenessInfo(LivenessInfo.create(0, 0)); - builder.add(row.build()); - - return builder.build(); - } - - private static ColumnMetadata column(TableMetadata metadata, String name) - { - return metadata.getColumn(new ColumnIdentifier(name, true)); - } - - private static TxnReference reference(TxnDataName name, TableMetadata metadata, String column) - { - return new TxnReference(name, column(metadata, column), null); - } } diff --git a/test/unit/org/apache/cassandra/service/accord/txn/TxnBuilder.java b/test/unit/org/apache/cassandra/service/accord/txn/TxnBuilder.java index fe335a03cf..8edb06afd2 100644 --- a/test/unit/org/apache/cassandra/service/accord/txn/TxnBuilder.java +++ b/test/unit/org/apache/cassandra/service/accord/txn/TxnBuilder.java @@ -69,7 +69,7 @@ public class TxnBuilder return withRead(name, query, VariableSpecifications.empty()); } - public TxnBuilder withRead(TxnDataName name, String query, VariableSpecifications bindVariables, Object... values) + private TxnBuilder withRead(TxnDataName name, String query, VariableSpecifications bindVariables, Object... values) { SelectStatement.RawStatement parsed = (SelectStatement.RawStatement) QueryProcessor.parseStatement(query); // the parser will only let us define a ref name if we're parsing a transaction, which we're not --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org