This is an automated email from the ASF dual-hosted git repository.
blerer pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 5cf62c6 Add support for string concatenations through the + operator
5cf62c6 is described below
commit 5cf62c6c02322505db9260d2aa9031386326fc75
Author: Manish Ghildiyal <[email protected]>
AuthorDate: Sat Dec 18 18:26:31 2021 +0100
Add support for string concatenations through the + operator
Patch by Manish Ghildiyal; review by Benjamin Lerer, Berenguer Blassi,
Brandon Williams for CASSANDRA-17190
---
CHANGES.txt | 1 +
NEWS.txt | 1 +
src/java/org/apache/cassandra/cql3/Constants.java | 14 +++-
.../cassandra/cql3/functions/OperationFcts.java | 92 ++++++++++++++++++----
.../apache/cassandra/db/marshal/StringType.java | 13 +++
.../cql3/functions/OperationFctsTest.java | 14 ++++
6 files changed, 118 insertions(+), 17 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 2a313ab..51e39bf 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.1
+ * Add support for string concatenations through the + operator
(CASSANDRA-17190)
* Limit the maximum hints size per host (CASSANDRA-17142)
* Add a virtual table for exposing batch metrics (CASSANDRA-17225)
* Flatten guardrails config (CASSANDRA-17353)
diff --git a/NEWS.txt b/NEWS.txt
index f5d76d5..26a1c8d 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -38,6 +38,7 @@ using the provided 'sstableupgrade' tool.
New features
------------
+ - Support for String concatenation has been added through the + operator.
- New configuration max_hints_size_per_host to limit the size of local
hints files per host in megabytes. Setting to
non-positive value disables the limit, which is the default behavior.
Setting to a positive value to ensure
the total size of the hints files per host does not exceed the limit.
diff --git a/src/java/org/apache/cassandra/cql3/Constants.java
b/src/java/org/apache/cassandra/cql3/Constants.java
index 3457e33..e8989ad 100644
--- a/src/java/org/apache/cassandra/cql3/Constants.java
+++ b/src/java/org/apache/cassandra/cql3/Constants.java
@@ -20,6 +20,7 @@ package org.apache.cassandra.cql3;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,7 +45,18 @@ public abstract class Constants
public enum Type
{
- STRING,
+ STRING
+ {
+ public AbstractType<?> getPreferedTypeFor(String text)
+ {
+ if(Charset.forName("US-ASCII").newEncoder().canEncode(text))
+ {
+ return AsciiType.instance;
+ }
+
+ return UTF8Type.instance;
+ }
+ },
INTEGER
{
public AbstractType<?> getPreferedTypeFor(String text)
diff --git a/src/java/org/apache/cassandra/cql3/functions/OperationFcts.java
b/src/java/org/apache/cassandra/cql3/functions/OperationFcts.java
index 4994660..b00ced7 100644
--- a/src/java/org/apache/cassandra/cql3/functions/OperationFcts.java
+++ b/src/java/org/apache/cassandra/cql3/functions/OperationFcts.java
@@ -53,14 +53,24 @@ public final class OperationFcts
{
return type.addDuration(temporal, duration);
}
+
+ @Override
+ protected ByteBuffer excuteOnStrings(StringType resultType,
+ StringType leftType,
+ ByteBuffer left,
+ StringType rightType,
+ ByteBuffer right)
+ {
+ return resultType.concat(leftType, left, rightType, right);
+ }
},
SUBSTRACTION('-', "_substract")
{
protected ByteBuffer executeOnNumerics(NumberType<?> resultType,
- NumberType<?> leftType,
- ByteBuffer left,
- NumberType<?> rightType,
- ByteBuffer right)
+ NumberType<?> leftType,
+ ByteBuffer left,
+ NumberType<?> rightType,
+ ByteBuffer right)
{
return resultType.substract(leftType, left, rightType, right);
}
@@ -76,10 +86,10 @@ public final class OperationFcts
MULTIPLICATION('*', "_multiply")
{
protected ByteBuffer executeOnNumerics(NumberType<?> resultType,
- NumberType<?> leftType,
- ByteBuffer left,
- NumberType<?> rightType,
- ByteBuffer right)
+ NumberType<?> leftType,
+ ByteBuffer left,
+ NumberType<?> rightType,
+ ByteBuffer right)
{
return resultType.multiply(leftType, left, rightType, right);
}
@@ -87,10 +97,10 @@ public final class OperationFcts
DIVISION('/', "_divide")
{
protected ByteBuffer executeOnNumerics(NumberType<?> resultType,
- NumberType<?> leftType,
- ByteBuffer left,
- NumberType<?> rightType,
- ByteBuffer right)
+ NumberType<?> leftType,
+ ByteBuffer left,
+ NumberType<?> rightType,
+ ByteBuffer right)
{
return resultType.divide(leftType, left, rightType, right);
}
@@ -98,10 +108,10 @@ public final class OperationFcts
MODULO('%', "_modulo")
{
protected ByteBuffer executeOnNumerics(NumberType<?> resultType,
- NumberType<?> leftType,
- ByteBuffer left,
- NumberType<?> rightType,
- ByteBuffer right)
+ NumberType<?> leftType,
+ ByteBuffer left,
+ NumberType<?> rightType,
+ ByteBuffer right)
{
return resultType.mod(leftType, left, rightType, right);
}
@@ -155,6 +165,25 @@ public final class OperationFcts
}
/**
+ * Executes the operation between the specified string operand.
+ *
+ * @param resultType the result type of the operation
+ * @param leftType the type of the left operand
+ * @param left the left operand
+ * @param rightType the type of the right operand
+ * @param right the right operand
+ * @return the operation result
+ */
+ protected ByteBuffer excuteOnStrings(StringType resultType,
+ StringType leftType,
+ ByteBuffer left,
+ StringType rightType,
+ ByteBuffer right)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
* Returns the {@code OPERATOR} associated to the specified function.
* @param functionName the function name
* @return the {@code OPERATOR} associated to the specified function
@@ -221,9 +250,19 @@ public final class OperationFcts
functions.add(new
TemporalOperationFunction(SimpleDateType.instance, operation));
}
+ addStringConcatenations(functions);
+
return functions;
}
+ private static void addStringConcatenations(List<Function> functions)
+ {
+ functions.add(new StringOperationFunction(UTF8Type.instance,
UTF8Type.instance, OPERATION.ADDITION, UTF8Type.instance));
+ functions.add(new StringOperationFunction(AsciiType.instance,
AsciiType.instance, OPERATION.ADDITION, AsciiType.instance));
+ functions.add(new StringOperationFunction(UTF8Type.instance,
AsciiType.instance, OPERATION.ADDITION, UTF8Type.instance));
+ functions.add(new StringOperationFunction(UTF8Type.instance,
UTF8Type.instance, OPERATION.ADDITION, AsciiType.instance));
+ }
+
/**
* Checks if the function with the specified name is an operation.
*
@@ -415,6 +454,27 @@ public final class OperationFcts
}
}
+ private static class StringOperationFunction extends OperationFunction
+ {
+ public StringOperationFunction(StringType returnType,
+ StringType left,
+ OPERATION operation,
+ StringType right)
+ {
+ super(returnType, left, operation, right);
+ }
+
+ @Override
+ protected ByteBuffer doExecute(ByteBuffer left, OPERATION operation,
ByteBuffer right)
+ {
+ StringType leftType = (StringType) argTypes().get(0);
+ StringType rightType = (StringType) argTypes().get(1);
+ StringType resultType = (StringType) returnType();
+
+ return operation.excuteOnStrings(resultType, leftType, left,
rightType, right);
+ }
+ }
+
/**
* Function that execute operations on temporals (timestamp, date, ...).
*/
diff --git a/src/java/org/apache/cassandra/db/marshal/StringType.java
b/src/java/org/apache/cassandra/db/marshal/StringType.java
index f9ce444..29aff58 100644
--- a/src/java/org/apache/cassandra/db/marshal/StringType.java
+++ b/src/java/org/apache/cassandra/db/marshal/StringType.java
@@ -18,10 +18,23 @@
package org.apache.cassandra.db.marshal;
+import java.nio.ByteBuffer;
+
public abstract class StringType extends AbstractType<String>
{
protected StringType(ComparisonType comparisonType)
{
super(comparisonType);
}
+
+ public ByteBuffer concat(StringType leftType,
+ ByteBuffer left,
+ StringType rightType,
+ ByteBuffer right)
+ {
+ String leftS = leftType.compose(left);
+ String rightS = rightType.compose(right);
+
+ return decompose(leftS + rightS);
+ }
}
diff --git
a/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
b/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
index 053283d..58c2c29 100644
--- a/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
+++ b/test/unit/org/apache/cassandra/cql3/functions/OperationFctsTest.java
@@ -33,6 +33,20 @@ import org.apache.cassandra.transport.ProtocolVersion;
public class OperationFctsTest extends CQLTester
{
+
+ @Test
+ public void testStringConcatenation() throws Throwable
+ {
+ createTable("CREATE TABLE %s (a text, b ascii, c text, PRIMARY KEY(a,
b, c))");
+ execute("INSERT INTO %S (a, b, c) VALUES ('जॉन', 'Doe', 'जॉन Doe')");
+
+ assertColumnNames(execute("SELECT a + a, a + b, b + a, b + b FROM %s
WHERE a = 'जॉन' AND b = 'Doe' AND c = 'जॉन Doe'"),
+ "a + a", "a + b", "b + a", "b + b");
+
+ assertRows(execute("SELECT a + ' ' + a, a + ' ' + b, b + ' ' + a, b +
' ' + b FROM %s WHERE a = 'जॉन' AND b = 'Doe' AND c = 'जॉन Doe'"),
+ row("जॉन जॉन", "जॉन Doe", "Doe जॉन", "Doe Doe"));
+ }
+
@Test
public void testSingleOperations() throws Throwable
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]