This is an automated email from the ASF dual-hosted git repository.
xiangfu0 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new e51b4e4878d [UUID 4c] CASE, IN and comparison transforms over the
logical UUID type (#19183)
e51b4e4878d is described below
commit e51b4e4878d05c12cd9ee4bb94f1cde757a81aab
Author: Xiang Fu <[email protected]>
AuthorDate: Fri Aug 7 21:37:43 2026 -0700
[UUID 4c] CASE, IN and comparison transforms over the logical UUID type
(#19183)
---
.../function/BinaryOperatorTransformFunction.java | 22 +++++--
.../transform/function/CaseTransformFunction.java | 14 +++--
.../BinaryOperatorTransformFunctionTest.java | 30 +++++++++
.../function/CaseTransformFunctionTest.java | 73 ++++++++++++++++++----
.../function/InTransformFunctionTest.java | 39 ++++++++++++
5 files changed, 154 insertions(+), 24 deletions(-)
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunction.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunction.java
index 77d0f89c1dc..f6a2101d43b 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunction.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunction.java
@@ -107,15 +107,16 @@ public abstract class BinaryOperatorTransformFunction
extends BaseTransformFunct
_leftTransformFunction = arguments.get(0);
_rightTransformFunction = arguments.get(1);
DataType leftDataType =
_leftTransformFunction.getResultMetadata().getDataType();
+ DataType rightDataType =
_rightTransformFunction.getResultMetadata().getDataType();
_leftStoredType = leftDataType.getStoredType();
- _rightStoredType =
_rightTransformFunction.getResultMetadata().getDataType().getStoredType();
+ _rightStoredType = rightDataType.getStoredType();
// Data type check: left and right types should be compatible.
if (_leftStoredType == DataType.BYTES || _rightStoredType ==
DataType.BYTES) {
Preconditions.checkState(_leftStoredType == _rightStoredType,
String.format(
"Unsupported data type for comparison: [Left Transform Function [%s]
result type is [%s], Right Transform "
- + "Function [%s] result type is [%s]]",
_leftTransformFunction.getName(), _leftStoredType,
- _rightTransformFunction.getName(), _rightStoredType));
+ + "Function [%s] result type is [%s]]",
getTransformFunctionDisplayName(_leftTransformFunction),
+ _leftStoredType,
getTransformFunctionDisplayName(_rightTransformFunction), _rightStoredType));
}
// Create predicate evaluator when the right side is a literal
@@ -689,8 +690,15 @@ public abstract class BinaryOperatorTransformFunction
extends BaseTransformFunct
private IllegalStateException illegalState() {
throw new IllegalStateException(String.format(
"Unsupported data type for comparison: [Left Transform Function [%s]
result type is [%s], Right "
- + "Transform Function [%s] result type is [%s]]",
_leftTransformFunction.getName(), _leftStoredType,
- _rightTransformFunction.getName(), _rightStoredType));
+ + "Transform Function [%s] result type is [%s]]",
getTransformFunctionDisplayName(_leftTransformFunction),
+ _leftStoredType,
getTransformFunctionDisplayName(_rightTransformFunction), _rightStoredType));
+ }
+
+ private static String getTransformFunctionDisplayName(TransformFunction
transformFunction) {
+ if (transformFunction instanceof IdentifierTransformFunction) {
+ return ((IdentifierTransformFunction) transformFunction).getColumnName();
+ }
+ return transformFunction.getName();
}
private void fillResultString(ValueBlock valueBlock, int length) {
@@ -704,8 +712,10 @@ public abstract class BinaryOperatorTransformFunction
extends BaseTransformFunct
private void fillResultBytes(ValueBlock valueBlock, int length) {
byte[][] leftBytesValues =
_leftTransformFunction.transformToBytesValuesSV(valueBlock);
byte[][] rightBytesValues =
_rightTransformFunction.transformToBytesValuesSV(valueBlock);
+ // ByteArray.compare is unsigned byte-wise lexicographic; for canonical
16-byte big-endian UUIDs this is
+ // equivalent to UuidUtils.compare's unsigned 64-bit-word ordering, so a
single comparator handles both.
for (int i = 0; i < length; i++) {
- _intValuesSV[i] = getIntResult((ByteArray.compare(leftBytesValues[i],
rightBytesValues[i])));
+ _intValuesSV[i] = getIntResult(ByteArray.compare(leftBytesValues[i],
rightBytesValues[i]));
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
index eac10def968..0822ddd1806 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunction.java
@@ -207,10 +207,12 @@ public class CaseTransformFunction extends
ComputeDifferentlyWhenNullHandlingEna
case JSON:
break;
case BYTES:
+ case UUID:
try {
- BytesUtils.toBytes(literal);
+ byte[] bytes = BytesUtils.toBytes(literal);
+ Preconditions.checkArgument(dataType != DataType.UUID ||
bytes.length == dataType.size());
} catch (Exception e) {
- throw new IllegalArgumentException("Invalid literal: " + literal + "
for BYTES");
+ throw new IllegalArgumentException("Invalid literal: " + literal + "
for " + dataType);
}
break;
default:
@@ -827,15 +829,16 @@ public class CaseTransformFunction extends
ComputeDifferentlyWhenNullHandlingEna
final RoaringBitmap bitmap = new RoaringBitmap();
int[] selected = getSelectedArray(valueBlock, true);
int numDocs = valueBlock.getNumDocs();
- initStringValuesSV(numDocs);
+ initBytesValuesSV(numDocs);
int numThenStatements = _thenStatements.size();
BitSet unselectedDocs = new BitSet();
unselectedDocs.set(0, numDocs);
Map<Integer, Pair<byte[][], RoaringBitmap>> thenStatementsIndexToValues =
new HashMap<>();
for (int i = 0; i < numThenStatements; i++) {
if (_computeThenStatements[i]) {
- thenStatementsIndexToValues.put(i,
ImmutablePair.of(_thenStatements.get(i).transformToBytesValuesSV(valueBlock),
- _thenStatements.get(i).getNullBitmap(valueBlock)));
+ thenStatementsIndexToValues.put(i,
+
ImmutablePair.of(_thenStatements.get(i).transformToBytesValuesSV(valueBlock),
+ _thenStatements.get(i).getNullBitmap(valueBlock)));
}
}
for (int docId = 0; docId < numDocs; docId++) {
@@ -872,6 +875,7 @@ public class CaseTransformFunction extends
ComputeDifferentlyWhenNullHandlingEna
return _bytesValuesSV;
}
+
@Override
public RoaringBitmap getNullBitmap(ValueBlock valueBlock) {
int[] selected = getSelectedArray(valueBlock, true);
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunctionTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunctionTest.java
index fa32ced888a..8ddfa1d6db1 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunctionTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/BinaryOperatorTransformFunctionTest.java
@@ -23,6 +23,7 @@ import
org.apache.pinot.common.request.context.RequestContextUtils;
import org.apache.pinot.core.operator.transform.TransformResultMetadata;
import org.apache.pinot.spi.data.FieldSpec.DataType;
import org.apache.pinot.spi.exception.BadQueryRequestException;
+import org.apache.pinot.spi.utils.UuidUtils;
import org.roaringbitmap.RoaringBitmap;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -256,6 +257,35 @@ public abstract class BinaryOperatorTransformFunctionTest
extends BaseTransformF
testTransformFunctionWithNull(transformFunction, expectedValues, bitmap);
}
+ @Test
+ public void testBinaryOperatorTransformFunctionUUID() {
+ String functionName = getFunctionName();
+ String uuidLiteral = UuidUtils.toString(_uuidSVValues[0]);
+ ExpressionContext expression = RequestContextUtils.getExpression(
+ String.format("%s(%s, CAST('%s' AS UUID))", functionName,
UUID_SV_COLUMN, uuidLiteral));
+ TransformFunction transformFunction =
TransformFunctionFactory.get(expression, _dataSourceMap);
+ boolean[] expectedValues = new boolean[NUM_ROWS];
+ for (int i = 0; i < NUM_ROWS; i++) {
+ expectedValues[i] = getExpectedValue(UuidUtils.compare(_uuidSVValues[i],
_uuidSVValues[0]));
+ }
+ testTransformFunction(transformFunction, expectedValues);
+ }
+
+ @Test
+ public void testBinaryOperatorTransformFunctionUUIDNoDict() {
+ String functionName = getFunctionName();
+ String uuidLiteral = UuidUtils.toString(_uuidSVValues[0]);
+ ExpressionContext expression = RequestContextUtils.getExpression(
+ String.format("%s(CAST(CAST(%s AS STRING) AS UUID), CAST('%s' AS
UUID))", functionName, UUID_SV_COLUMN,
+ uuidLiteral));
+ TransformFunction transformFunction =
TransformFunctionFactory.get(expression, _dataSourceMap);
+ boolean[] expectedValues = new boolean[NUM_ROWS];
+ for (int i = 0; i < NUM_ROWS; i++) {
+ expectedValues[i] = getExpectedValue(UuidUtils.compare(_uuidSVValues[i],
_uuidSVValues[0]));
+ }
+ testTransformFunction(transformFunction, expectedValues);
+ }
+
@Test(dataProvider = "testIllegalArguments", expectedExceptions =
{BadQueryRequestException.class})
public void testIllegalArguments(String expressionStr) {
ExpressionContext expression =
RequestContextUtils.getExpression(expressionStr);
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunctionTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunctionTest.java
index f7acf5ff1be..47c83ad48d3 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunctionTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/CaseTransformFunctionTest.java
@@ -29,6 +29,7 @@ import
org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.RequestContextUtils;
import org.apache.pinot.spi.data.FieldSpec.DataType;
import org.apache.pinot.spi.utils.BytesUtils;
+import org.apache.pinot.spi.utils.UuidUtils;
import org.roaringbitmap.RoaringBitmap;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
@@ -36,6 +37,7 @@ import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertTrue;
public class CaseTransformFunctionTest extends BaseTransformFunctionTest {
@@ -137,7 +139,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
String expression = String.format("CASE WHEN %s THEN %s ELSE 10 END",
predicate, INT_SV_COLUMN);
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.INT);
int[] intValues =
transformFunction.transformToIntValuesSV(_projectionBlock);
assertNotEquals(intValues[index], expectedValues[0]);
@@ -167,7 +169,14 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
String.format("CASE WHEN true THEN %s ELSE %s END", INT_SV_COLUMN,
BYTES_SV_COLUMN),
String.format("CASE WHEN true THEN 100 ELSE %s END", TIMESTAMP_COLUMN),
String.format("CASE WHEN true THEN 100 ELSE %s END", STRING_SV_COLUMN),
- String.format("CASE WHEN true THEN 100 ELSE %s END", BYTES_SV_COLUMN)
+ String.format("CASE WHEN true THEN 100 ELSE %s END", BYTES_SV_COLUMN),
+ "CASE WHEN true THEN CAST('550e8400-e29b-41d4-a716-446655440000' AS
UUID) ELSE 'not-a-uuid' END",
+ "CASE WHEN true THEN CAST('550e8400-e29b-41d4-a716-446655440000' AS
UUID) "
+ + "ELSE '550e8400-e29b-41d4-a716-446655440001' END",
+ String.format("CASE WHEN true THEN
CAST('550e8400-e29b-41d4-a716-446655440000' AS UUID) ELSE '%s' END",
+ "00".repeat(15)),
+ String.format("CASE WHEN true THEN
CAST('550e8400-e29b-41d4-a716-446655440000' AS UUID) ELSE '%s' END",
+ "00".repeat(17))
};
//@formatter:on
}
@@ -177,12 +186,50 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
TransformFunctionFactory.get(RequestContextUtils.getExpression(expression),
_dataSourceMap);
}
+ @Test
+ public void testCaseTransformFunctionWithUuidResults() {
+ String uuidValue = "550e8400-e29b-41d4-a716-446655440000";
+ byte[] uuidBytes = UuidUtils.toBytes(uuidValue);
+ ExpressionContext expression = RequestContextUtils.getExpression(
+ "CASE WHEN true THEN CAST('" + uuidValue.toUpperCase() + "' AS UUID)
ELSE '"
+ + BytesUtils.toHexString(uuidBytes) + "' END");
+ TransformFunction transformFunction =
TransformFunctionFactory.get(expression, _dataSourceMap);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.UUID);
+ byte[][] expectedValues = new byte[NUM_ROWS][];
+ for (int i = 0; i < NUM_ROWS; i++) {
+ expectedValues[i] = uuidBytes;
+ }
+ testTransformFunction(transformFunction, expectedValues);
+ }
+
+ @Test
+ public void testCaseTransformFunctionWithUuidHexLiteralBranch() {
+ String whenUuidValue = "550e8400-e29b-41d4-a716-446655440000";
+ String elseUuidValue = "550e8400-e29b-41d4-a716-446655440001";
+ byte[] whenUuidBytes = UuidUtils.toBytes(whenUuidValue);
+ byte[] elseUuidBytes = UuidUtils.toBytes(elseUuidValue);
+ ExpressionContext expression = RequestContextUtils.getExpression(
+ String.format("CASE WHEN %s < 2 THEN '%s' ELSE CAST('%s' AS UUID)
END", INT_SV_COLUMN,
+ BytesUtils.toHexString(whenUuidBytes).toUpperCase(),
elseUuidValue));
+ TransformFunction transformFunction =
TransformFunctionFactory.get(expression, _dataSourceMap);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.UUID);
+
+ byte[][] expectedValues = new byte[NUM_ROWS][];
+ for (int i = 0; i < NUM_ROWS; i++) {
+ expectedValues[i] = _intSVValues[i] < 2 ? whenUuidBytes : elseUuidBytes;
+ }
+ testTransformFunction(transformFunction, expectedValues);
+ }
+
+
@Test
public void testCaseTransformationWithNullColumn() {
ExpressionContext expression = RequestContextUtils.getExpression(
String.format("CASE WHEN %s IS NULL THEN 'aaa' ELSE 'bbb' END",
STRING_ALPHANUM_NULL_SV_COLUMN));
TransformFunction transformFunction =
TransformFunctionFactory.getNullHandlingEnabled(expression, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
Assert.assertEquals(transformFunction.getName(), "case");
Assert.assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.STRING);
@@ -202,7 +249,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
ExpressionContext expression = RequestContextUtils.getExpression(
String.format("CASE WHEN %s IS NULL THEN NULL ELSE 'bbb' END",
STRING_ALPHANUM_NULL_SV_COLUMN));
TransformFunction transformFunction =
TransformFunctionFactory.getNullHandlingEnabled(expression, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
Assert.assertEquals(transformFunction.getName(), "case");
Assert.assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.STRING);
String[] expectedValues = new String[NUM_ROWS];
@@ -222,7 +269,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
ExpressionContext expression = RequestContextUtils.getExpression(
String.format("CASE WHEN %s IS NULL THEN 'aaa' END",
STRING_ALPHANUM_NULL_SV_COLUMN));
TransformFunction transformFunction =
TransformFunctionFactory.getNullHandlingEnabled(expression, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
Assert.assertEquals(transformFunction.getName(), "case");
Assert.assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.STRING);
@@ -618,7 +665,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.INT);
testTransformFunction(transformFunction, expectedValues);
}
@@ -628,7 +675,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.LONG);
testTransformFunction(transformFunction, expectedValues);
}
@@ -638,7 +685,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.FLOAT);
testTransformFunction(transformFunction, expectedValues);
}
@@ -648,7 +695,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.DOUBLE);
testTransformFunction(transformFunction, expectedValues);
}
@@ -658,7 +705,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.BIG_DECIMAL);
testTransformFunction(transformFunction, expectedValues);
}
@@ -668,7 +715,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.STRING);
testTransformFunction(transformFunction, expectedValues);
}
@@ -678,7 +725,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.BYTES);
testTransformFunction(transformFunction, expectedValues);
}
@@ -688,7 +735,7 @@ public class CaseTransformFunctionTest extends
BaseTransformFunctionTest {
for (String expression : expressions) {
ExpressionContext expressionContext =
RequestContextUtils.getExpression(expression);
TransformFunction transformFunction =
TransformFunctionFactory.get(expressionContext, _dataSourceMap);
- Assert.assertTrue(transformFunction instanceof CaseTransformFunction);
+ assertTrue(transformFunction instanceof CaseTransformFunction);
assertEquals(transformFunction.getResultMetadata().getDataType(),
DataType.TIMESTAMP);
testTransformFunction(transformFunction, expectedValues);
}
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/InTransformFunctionTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/InTransformFunctionTest.java
index 983758c3fc2..2c8176a4a65 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/InTransformFunctionTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/operator/transform/function/InTransformFunctionTest.java
@@ -20,15 +20,19 @@ package org.apache.pinot.core.operator.transform.function;
import com.google.common.collect.Sets;
import java.util.Arrays;
+import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.pinot.common.function.TransformFunctionType;
import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.RequestContextUtils;
+import org.apache.pinot.spi.exception.BadQueryRequestException;
import org.apache.pinot.spi.utils.ByteArray;
import org.apache.pinot.spi.utils.BytesUtils;
import org.apache.pinot.spi.utils.CommonConstants.NullValuePlaceHolder;
+import org.apache.pinot.spi.utils.UuidUtils;
import org.roaringbitmap.RoaringBitmap;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@@ -223,6 +227,41 @@ public class InTransformFunctionTest extends
BaseTransformFunctionTest {
}
}
+ @Test(dataProvider = "uuidInExpressions")
+ public void testUuidInTransformFunction(String expressionStr) {
+ ExpressionContext expression =
RequestContextUtils.getExpression(expressionStr);
+ TransformFunction transformFunction =
TransformFunctionFactory.get(expression, _dataSourceMap);
+ assertTrue(transformFunction instanceof InTransformFunction);
+ assertEquals(transformFunction.getName(),
TransformFunctionType.IN.getName());
+
+ Set<ByteArray> inValues = Sets.newHashSet(new ByteArray(_uuidSVValues[2]),
new ByteArray(_uuidSVValues[5]));
+ int[] intValues =
transformFunction.transformToIntValuesSV(_projectionBlock);
+ for (int i = 0; i < NUM_ROWS; i++) {
+ if (i == 2 || i == 5) {
+ assertEquals(intValues[i], 1);
+ }
+ assertEquals(intValues[i], inValues.contains(new
ByteArray(_uuidSVValues[i])) ? 1 : 0);
+ }
+ }
+
+ @DataProvider(name = "uuidInExpressions")
+ public Object[][] uuidInExpressions() {
+ return new Object[][]{
+ {String.format("%s IN ('%s','%s')", UUID_SV_COLUMN,
+ BytesUtils.toHexString(_uuidSVValues[5]).toUpperCase(Locale.ROOT),
+ BytesUtils.toHexString(_uuidSVValues[2]))},
+ {String.format("%s IN (CAST('%s' AS UUID),CAST('%s' AS UUID))",
UUID_SV_COLUMN,
+ UuidUtils.toString(_uuidSVValues[5]).toUpperCase(Locale.ROOT),
UuidUtils.toString(_uuidSVValues[2]))}
+ };
+ }
+
+ @Test(expectedExceptions = BadQueryRequestException.class)
+ public void testUuidInTransformFunctionRejectsBareCanonicalLiteral() {
+ ExpressionContext expression = RequestContextUtils.getExpression(
+ String.format("%s IN ('%s')", UUID_SV_COLUMN,
UuidUtils.toString(_uuidSVValues[5])));
+ TransformFunctionFactory.get(expression, _dataSourceMap);
+ }
+
@Test
public void testInTransformFunctionNullLiteralReturnsNull() {
String expressionStr = String.format("%s IN (%s)", "NULL",
INT_SV_NULL_COLUMN);
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]