dcapwell commented on code in PR #1962:
URL: https://github.com/apache/cassandra/pull/1962#discussion_r1041553899
##########
src/java/org/apache/cassandra/serializers/ListSerializer.java:
##########
@@ -224,10 +226,29 @@ public Class<List<T>> getType()
}
@Override
- public ByteBuffer getSerializedValue(ByteBuffer collection, ByteBuffer
key, AbstractType<?> comparator)
+ public ByteBuffer getSerializedValue(ByteBuffer collection, ByteBuffer
index, AbstractType<?> comparator)
{
- // We don't allow selecting an element of a list, so we don't need
this.
- throw new UnsupportedOperationException();
+ try
+ {
+ ProtocolVersion version = ProtocolVersion.V3;
Review Comment:
hard coding this could come to bite us later on... not sure how we would
solve this without changing the method signature...
##########
src/antlr/Parser.g:
##########
@@ -651,6 +717,102 @@ batchStatementObjective returns
[ModificationStatement.Parsed statement]
| d=deleteStatement { $statement = d; }
;
+/**
+ * ex. conditional update returning pre-update values
+ *
+ * BEGIN TRANSACTION
+ * LET row1 = (SELECT * FROM <table> WHERE k=1 AND c=2);
+ * LET row2 = (SELECT * FROM <table> WHERE k=2 AND c=2);
+ * SELECT row1.v, row2.v;
+ * IF row1.v = 3 AND row2.v = 4 THEN
+ * UPDATE <table> SET v = row1.v + 1 WHERE k = 1 AND c = 2;
+ * END IF
+ * COMMIT TRANSACTION
+ *
+ * ex. read-only transaction
+ *
+ * BEGIN TRANSACTION
+ * SELECT * FROM <table> WHERE k=1 AND c=2;
+ * COMMIT TRANSACTION
+ *
+ * ex. write-only transaction
+ *
+ * BEGIN TRANSACTION
+ * INSERT INTO <table> (k, c, v) VALUES (0, 0, 1);
+ * COMMIT TRANSACTION
+ */
+batchTxnStatement returns [TransactionStatement.Parsed expr]
+ @init {
+ isParsingTxn = true;
+ List<SelectStatement.RawStatement> assignments = new ArrayList<>();
+ SelectStatement.RawStatement select = null;
+ List<RowDataReference.Raw> returning = null;
+ List<ModificationStatement.Parsed> updates = new ArrayList<>();
+ }
+ : K_BEGIN K_TRANSACTION
+ ( let=letStatement ';' { assignments.add(let); })*
+ ( ( (selectStatement) => s=selectStatement ';' { select = s; }) | (
K_SELECT drs=rowDataReferences ';' { returning = drs; }) )?
+ ( K_IF conditions=txnConditions K_THEN { isTxnConditional = true; } )?
+ ( upd=batchStatementObjective ';' { updates.add(upd); } )*
+ ( {!isTxnConditional}? (K_COMMIT K_TRANSACTION) | {isTxnConditional}?
(K_END K_IF K_COMMIT K_TRANSACTION))
+ {
+ $expr = new TransactionStatement.Parsed(assignments, select,
returning, updates, conditions, references);
+ }
+ ;
+ finally { isParsingTxn = false; }
+
+rowDataReferences returns [List<RowDataReference.Raw> refs]
+ : r1=rowDataReference { refs = new ArrayList<RowDataReference.Raw>();
refs.add(r1); } (',' rN=rowDataReference { refs.add(rN); })*
+ ;
+
+rowDataReference returns [RowDataReference.Raw rawRef]
+ @init { Selectable.RawIdentifier tuple = null; Selectable.Raw selectable =
null; }
+ @after { $rawRef = newRowDataReference(tuple, selectable); }
+ : t=sident ('.' s=referenceSelection)? { tuple = t; selectable = s; }
+ ;
+
+referenceSelection returns [Selectable.Raw s]
+ : g=referenceSelectionWithoutField m=selectorModifier[g] {$s = m;}
+ ;
+
+referenceSelectionWithoutField returns [Selectable.Raw s]
+ @init { Selectable.Raw tmp = null; }
+ @after { $s = tmp; }
+ : sn=sident { tmp=sn; }
+ | (selectionTypeHint)=> h=selectionTypeHint { tmp=h; }
+ | t=selectionTupleOrNestedSelector { tmp=t; }
+ | l=selectionList { tmp=l; }
+ | m=selectionMapOrSet { tmp=m; }
+ // UDTs are equivalent to maps from the syntax point of view, so the final
decision will be done in Selectable.WithMapOrUdt
+ ;
+
+txnConditions returns [List<ConditionStatement.Raw> conditions]
+ @init { conditions = new ArrayList<ConditionStatement.Raw>(); }
+ : txnColumnCondition[conditions] ( K_AND txnColumnCondition[conditions] )*
Review Comment:
no `OR` support?
##########
src/java/org/apache/cassandra/service/StorageService.java:
##########
@@ -1522,6 +1587,17 @@ public long getTruncateRpcTimeout()
return DatabaseDescriptor.getTruncateRpcTimeout(MILLISECONDS);
}
+ public void setTransactionTimeout(long value)
+ {
+ DatabaseDescriptor.setTransactionTimeout(value);
+ logger.info("set transaction timeout to {} ms", value);
+ }
+
+ public long getTransactionTimeout()
+ {
+ return DatabaseDescriptor.getTransactionTimeout(MILLISECONDS);
+ }
Review Comment:
heh... checked trunk... no timeout uses `String`... and most don't give a
unit! =/
##########
src/antlr/Parser.g:
##########
@@ -651,6 +717,102 @@ batchStatementObjective returns
[ModificationStatement.Parsed statement]
| d=deleteStatement { $statement = d; }
;
+/**
+ * ex. conditional update returning pre-update values
+ *
+ * BEGIN TRANSACTION
+ * LET row1 = (SELECT * FROM <table> WHERE k=1 AND c=2);
+ * LET row2 = (SELECT * FROM <table> WHERE k=2 AND c=2);
+ * SELECT row1.v, row2.v;
+ * IF row1.v = 3 AND row2.v = 4 THEN
+ * UPDATE <table> SET v = row1.v + 1 WHERE k = 1 AND c = 2;
+ * END IF
+ * COMMIT TRANSACTION
+ *
+ * ex. read-only transaction
+ *
+ * BEGIN TRANSACTION
+ * SELECT * FROM <table> WHERE k=1 AND c=2;
+ * COMMIT TRANSACTION
+ *
+ * ex. write-only transaction
+ *
+ * BEGIN TRANSACTION
+ * INSERT INTO <table> (k, c, v) VALUES (0, 0, 1);
+ * COMMIT TRANSACTION
+ */
+batchTxnStatement returns [TransactionStatement.Parsed expr]
+ @init {
+ isParsingTxn = true;
+ List<SelectStatement.RawStatement> assignments = new ArrayList<>();
+ SelectStatement.RawStatement select = null;
+ List<RowDataReference.Raw> returning = null;
+ List<ModificationStatement.Parsed> updates = new ArrayList<>();
+ }
+ : K_BEGIN K_TRANSACTION
+ ( let=letStatement ';' { assignments.add(let); })*
+ ( ( (selectStatement) => s=selectStatement ';' { select = s; }) | (
K_SELECT drs=rowDataReferences ';' { returning = drs; }) )?
+ ( K_IF conditions=txnConditions K_THEN { isTxnConditional = true; } )?
+ ( upd=batchStatementObjective ';' { updates.add(upd); } )*
+ ( {!isTxnConditional}? (K_COMMIT K_TRANSACTION) | {isTxnConditional}?
(K_END K_IF K_COMMIT K_TRANSACTION))
+ {
+ $expr = new TransactionStatement.Parsed(assignments, select,
returning, updates, conditions, references);
+ }
+ ;
+ finally { isParsingTxn = false; }
+
+rowDataReferences returns [List<RowDataReference.Raw> refs]
+ : r1=rowDataReference { refs = new ArrayList<RowDataReference.Raw>();
refs.add(r1); } (',' rN=rowDataReference { refs.add(rN); })*
+ ;
+
+rowDataReference returns [RowDataReference.Raw rawRef]
+ @init { Selectable.RawIdentifier tuple = null; Selectable.Raw selectable =
null; }
+ @after { $rawRef = newRowDataReference(tuple, selectable); }
+ : t=sident ('.' s=referenceSelection)? { tuple = t; selectable = s; }
+ ;
+
+referenceSelection returns [Selectable.Raw s]
+ : g=referenceSelectionWithoutField m=selectorModifier[g] {$s = m;}
+ ;
+
+referenceSelectionWithoutField returns [Selectable.Raw s]
+ @init { Selectable.Raw tmp = null; }
+ @after { $s = tmp; }
+ : sn=sident { tmp=sn; }
+ | (selectionTypeHint)=> h=selectionTypeHint { tmp=h; }
+ | t=selectionTupleOrNestedSelector { tmp=t; }
+ | l=selectionList { tmp=l; }
+ | m=selectionMapOrSet { tmp=m; }
+ // UDTs are equivalent to maps from the syntax point of view, so the final
decision will be done in Selectable.WithMapOrUdt
+ ;
+
+txnConditions returns [List<ConditionStatement.Raw> conditions]
+ @init { conditions = new ArrayList<ConditionStatement.Raw>(); }
+ : txnColumnCondition[conditions] ( K_AND txnColumnCondition[conditions] )*
+ ;
+
+txnConditionKind returns [ConditionStatement.Kind op]
+ : '=' { $op = ConditionStatement.Kind.EQ; }
+ | '<' { $op = ConditionStatement.Kind.LT; }
+ | '<=' { $op = ConditionStatement.Kind.LTE; }
+ | '>' { $op = ConditionStatement.Kind.GT; }
+ | '>=' { $op = ConditionStatement.Kind.GTE; }
+ | '!=' { $op = ConditionStatement.Kind.NEQ; }
+ ;
+
+txnColumnCondition[List<ConditionStatement.Raw> conditions]
+ : lhs=rowDataReference
Review Comment:
pushed test to show this issue
org.apache.cassandra.distributed.test.accord.AccordCQLTest#testConditionRefSideHandling
##########
src/antlr/Parser.g:
##########
@@ -651,6 +717,102 @@ batchStatementObjective returns
[ModificationStatement.Parsed statement]
| d=deleteStatement { $statement = d; }
;
+/**
+ * ex. conditional update returning pre-update values
+ *
+ * BEGIN TRANSACTION
+ * LET row1 = (SELECT * FROM <table> WHERE k=1 AND c=2);
+ * LET row2 = (SELECT * FROM <table> WHERE k=2 AND c=2);
+ * SELECT row1.v, row2.v;
+ * IF row1.v = 3 AND row2.v = 4 THEN
+ * UPDATE <table> SET v = row1.v + 1 WHERE k = 1 AND c = 2;
+ * END IF
+ * COMMIT TRANSACTION
+ *
+ * ex. read-only transaction
+ *
+ * BEGIN TRANSACTION
+ * SELECT * FROM <table> WHERE k=1 AND c=2;
+ * COMMIT TRANSACTION
+ *
+ * ex. write-only transaction
+ *
+ * BEGIN TRANSACTION
+ * INSERT INTO <table> (k, c, v) VALUES (0, 0, 1);
+ * COMMIT TRANSACTION
+ */
+batchTxnStatement returns [TransactionStatement.Parsed expr]
+ @init {
+ isParsingTxn = true;
+ List<SelectStatement.RawStatement> assignments = new ArrayList<>();
+ SelectStatement.RawStatement select = null;
+ List<RowDataReference.Raw> returning = null;
+ List<ModificationStatement.Parsed> updates = new ArrayList<>();
+ }
+ : K_BEGIN K_TRANSACTION
+ ( let=letStatement ';' { assignments.add(let); })*
+ ( ( (selectStatement) => s=selectStatement ';' { select = s; }) | (
K_SELECT drs=rowDataReferences ';' { returning = drs; }) )?
+ ( K_IF conditions=txnConditions K_THEN { isTxnConditional = true; } )?
+ ( upd=batchStatementObjective ';' { updates.add(upd); } )*
+ ( {!isTxnConditional}? (K_COMMIT K_TRANSACTION) | {isTxnConditional}?
(K_END K_IF K_COMMIT K_TRANSACTION))
+ {
+ $expr = new TransactionStatement.Parsed(assignments, select,
returning, updates, conditions, references);
+ }
+ ;
+ finally { isParsingTxn = false; }
+
+rowDataReferences returns [List<RowDataReference.Raw> refs]
+ : r1=rowDataReference { refs = new ArrayList<RowDataReference.Raw>();
refs.add(r1); } (',' rN=rowDataReference { refs.add(rN); })*
+ ;
+
+rowDataReference returns [RowDataReference.Raw rawRef]
+ @init { Selectable.RawIdentifier tuple = null; Selectable.Raw selectable =
null; }
+ @after { $rawRef = newRowDataReference(tuple, selectable); }
+ : t=sident ('.' s=referenceSelection)? { tuple = t; selectable = s; }
+ ;
+
+referenceSelection returns [Selectable.Raw s]
+ : g=referenceSelectionWithoutField m=selectorModifier[g] {$s = m;}
+ ;
+
+referenceSelectionWithoutField returns [Selectable.Raw s]
+ @init { Selectable.Raw tmp = null; }
+ @after { $s = tmp; }
+ : sn=sident { tmp=sn; }
+ | (selectionTypeHint)=> h=selectionTypeHint { tmp=h; }
+ | t=selectionTupleOrNestedSelector { tmp=t; }
+ | l=selectionList { tmp=l; }
+ | m=selectionMapOrSet { tmp=m; }
+ // UDTs are equivalent to maps from the syntax point of view, so the final
decision will be done in Selectable.WithMapOrUdt
+ ;
+
+txnConditions returns [List<ConditionStatement.Raw> conditions]
+ @init { conditions = new ArrayList<ConditionStatement.Raw>(); }
+ : txnColumnCondition[conditions] ( K_AND txnColumnCondition[conditions] )*
+ ;
+
+txnConditionKind returns [ConditionStatement.Kind op]
+ : '=' { $op = ConditionStatement.Kind.EQ; }
+ | '<' { $op = ConditionStatement.Kind.LT; }
+ | '<=' { $op = ConditionStatement.Kind.LTE; }
+ | '>' { $op = ConditionStatement.Kind.GT; }
+ | '>=' { $op = ConditionStatement.Kind.GTE; }
+ | '!=' { $op = ConditionStatement.Kind.NEQ; }
+ ;
+
+txnColumnCondition[List<ConditionStatement.Raw> conditions]
+ : lhs=rowDataReference
Review Comment:
so has to be LHS?
```
IF 42 <= a.counter -- rejected?
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]