Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ExactMatch Filter for Non-Convertible Types; Use RangeFilter on QueryScope Vars #5587

Merged
merged 46 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
24f6f65
Fix ExactMatch Filter for Non-Convertible Types
nbauernfeind Jun 7, 2024
1bec5c3
Add LocalDate, LocalTime, LocalDateTime, ZoneDateTime Converters
nbauernfeind Jun 7, 2024
89eee34
Fix #5526 by Sharing Conversion With MatchFilter
nbauernfeind Jun 7, 2024
480bedf
Fix ZonedDateTime and Array Shenanigans
nbauernfeind Jun 7, 2024
45e69bb
cleanup personal review
nbauernfeind Jun 7, 2024
bd53581
spotless
nbauernfeind Jun 7, 2024
0786673
Allow Inverted Versions of Filter Regex
nbauernfeind Jun 7, 2024
b210076
Rename RangeFilter
nbauernfeind Jun 11, 2024
286f51b
f
nbauernfeind Jun 11, 2024
da8bcdf
Add failover to MatchFilter
nbauernfeind Jun 11, 2024
9b3fe23
reduce regex to single pattern
nbauernfeind Jun 11, 2024
7488c97
fix spotless
nbauernfeind Jun 12, 2024
df7e0b1
bugfix
nbauernfeind Jun 12, 2024
18a8ab7
where filter test fixes
nbauernfeind Jun 12, 2024
804d950
where filter factory test
nbauernfeind Jun 12, 2024
46bf831
Update engine/table/src/main/java/io/deephaven/engine/table/impl/sele…
nbauernfeind Jun 18, 2024
136c718
Update engine/table/src/main/java/io/deephaven/engine/table/impl/sele…
nbauernfeind Jun 18, 2024
e0951fe
Update engine/table/src/main/java/io/deephaven/engine/table/impl/sele…
nbauernfeind Jun 18, 2024
2795e17
Update engine/table/src/main/java/io/deephaven/engine/table/impl/sele…
nbauernfeind Jun 18, 2024
d098d21
Update engine/table/src/main/java/io/deephaven/engine/table/impl/sele…
nbauernfeind Jun 18, 2024
6982d74
Ryan's feedback
nbauernfeind Jun 18, 2024
61fb256
rename
nbauernfeind Jun 18, 2024
9d80d20
spotlesS
nbauernfeind Jun 18, 2024
b58f235
hard code mirroring
nbauernfeind Jun 18, 2024
4fc140f
Ryan's Comments Continued
nbauernfeind Jun 18, 2024
4e68b63
Merge remote-tracking branch 'upstream/main' into gh_5584
nbauernfeind Jun 18, 2024
5e5d4cb
other feedback
nbauernfeind Jun 21, 2024
aff8a28
more feedback from rnd1
nbauernfeind Jun 21, 2024
cf07196
spotless
nbauernfeind Jun 21, 2024
628fe02
quick fix
nbauernfeind Jun 21, 2024
73ffe40
whitespace fix
nbauernfeind Jun 21, 2024
15d66d5
Add fallback tests and bugfix
nbauernfeind Jun 21, 2024
1dbab30
Ryan's rnd2 direct suggestions.
nbauernfeind Jun 24, 2024
1befd4d
Ryan's rnd2 feedback
nbauernfeind Jun 24, 2024
1ddde7d
Quick compilation fixes
nbauernfeind Jun 24, 2024
24315c0
Few More Filter Delegation Fixes
nbauernfeind Jun 24, 2024
dd801eb
DateTimeUtil Tests
nbauernfeind Jun 24, 2024
eaf10ee
spotless
nbauernfeind Jun 24, 2024
e92cc09
Ryan's rnd3 feedback
nbauernfeind Jun 24, 2024
4441809
Merge remote-tracking branch 'upstream/main' into gh_5584
nbauernfeind Jun 24, 2024
3d211fc
Make ZonedDateTimeRangeFilter compare ZoneDateTimes
nbauernfeind Jun 24, 2024
c87ba9a
Force column names to take precedence
nbauernfeind Jun 24, 2024
e07f2f0
Fix type coercion from one numeric to another
nbauernfeind Jun 24, 2024
f18e93e
Make actual null work properly w/coercion
nbauernfeind Jun 25, 2024
45c4c35
Also coerce BigDecimal and BigInteger
nbauernfeind Jun 25, 2024
2ebba51
revert commented tests
nbauernfeind Jun 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.deephaven.engine.table.Table;
import io.deephaven.engine.table.TableDefinition;
import io.deephaven.engine.table.impl.QueryCompilerRequestProcessor;
import io.deephaven.engine.table.impl.lang.QueryLanguageFunctionUtils;
import io.deephaven.engine.table.impl.preview.DisplayWrapper;
import io.deephaven.engine.table.impl.DependencyStreamProvider;
import io.deephaven.engine.table.impl.indexer.DataIndexer;
Expand All @@ -24,6 +25,7 @@
import io.deephaven.util.SafeCloseable;
import io.deephaven.util.datastructures.CachingSupplier;
import io.deephaven.util.type.ArrayTypeUtils;
import io.deephaven.util.type.TypeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jpy.PyObject;
Expand Down Expand Up @@ -344,7 +346,14 @@ final boolean convertValue(
if (tableDefinition.getColumn(strValue) != null) {
// this is also a column name which needs to take precedence, and we can't convert it
throw new IllegalArgumentException(String.format(
"Failed to convert literal value <%s> for column \"%s\" of type %s; it is a column name",
"Failed to convert value <%s> for column \"%s\" of type %s; it is a column name",
strValue, column.getName(), column.getDataType().getName()));
}
if (strValue.endsWith("_")
&& tableDefinition.getColumn(strValue.substring(0, strValue.length() - 1)) != null) {
// this also a column array name which needs to take precedence, and we can't convert it
throw new IllegalArgumentException(String.format(
"Failed to convert value <%s> for column \"%s\" of type %s; it is a column array access name",
strValue, column.getName(), column.getDataType().getName()));
}

Expand Down Expand Up @@ -390,6 +399,18 @@ Object convertStringLiteral(String str) {
}
return Byte.parseByte(str);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Byte) {
nbauernfeind marked this conversation as resolved.
Show resolved Hide resolved
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.byteCast(boxer.get(paramValue));
}
};
}
if (cls == short.class) {
Expand All @@ -401,6 +422,18 @@ Object convertStringLiteral(String str) {
}
return Short.parseShort(str);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Short) {
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.shortCast(boxer.get(paramValue));
}
};
}
if (cls == int.class) {
Expand All @@ -412,6 +445,18 @@ Object convertStringLiteral(String str) {
}
return Integer.parseInt(str);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Integer) {
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.intCast(boxer.get(paramValue));
}
};
}
if (cls == long.class) {
Expand All @@ -423,6 +468,18 @@ Object convertStringLiteral(String str) {
}
return Long.parseLong(str);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Long) {
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.longCast(boxer.get(paramValue));
}
};
}
if (cls == float.class) {
Expand All @@ -434,6 +491,18 @@ Object convertStringLiteral(String str) {
}
return Float.parseFloat(str);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Float) {
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.floatCast(boxer.get(paramValue));
}
};
}
if (cls == double.class) {
Expand All @@ -445,6 +514,18 @@ Object convertStringLiteral(String str) {
}
return Double.parseDouble(str);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Double) {
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.doubleCast(boxer.get(paramValue));
}
};
}
if (cls == Boolean.class) {
Expand Down Expand Up @@ -485,6 +566,18 @@ Object convertStringLiteral(String str) {
}
return str.charAt(0);
}

@Override
Object convertParamValue(Object paramValue) {
paramValue = super.convertParamValue(paramValue);
if (paramValue instanceof Character) {
return paramValue;
}
// noinspection unchecked
final TypeUtils.TypeBoxer<Object> boxer =
(TypeUtils.TypeBoxer<Object>) TypeUtils.getTypeBoxer(paramValue.getClass());
return QueryLanguageFunctionUtils.charCast(boxer.get(paramValue));
}
};
}
if (cls == BigDecimal.class) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import junit.framework.TestCase;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;

Expand Down Expand Up @@ -1404,4 +1405,150 @@ public void testRangeFilterFallback() {
final WhereFilter realFilter = filter.getRealFilter();
Assert.eqTrue(realFilter instanceof ConditionFilter, "realFilter instanceof ConditionFilter");
}

@Test
public void testEnsureColumnsTakePrecedence() {
final Table table = emptyTable(10).update("X=i", "Y=i%2");
ExecutionContext.getContext().getQueryScope().putParam("Y", 5);

{
final Table r1 = table.where("X == Y");
final Table r2 = table.where("Y == X");
Assert.equals(r1.getRowSet(), "r1.getRowSet()", RowSetFactory.flat(2));
assertTableEquals(r1, r2);
}

{
final Table r1 = table.where("X >= Y");
final Table r2 = table.where("Y <= X");
Assert.equals(r1.getRowSet(), "r1.getRowSet()", RowSetFactory.flat(10));
assertTableEquals(r1, r2);
}

{
final Table r1 = table.where("X > Y");
final Table r2 = table.where("Y < X");
Assert.equals(r1.getRowSet(), "r1.getRowSet()", RowSetFactory.fromRange(2, 9));
assertTableEquals(r1, r2);
}

{
final Table r1 = table.where("X < Y");
final Table r2 = table.where("Y > X");
Assert.equals(r1.getRowSet(), "r1.getRowSet()", RowSetFactory.empty());
assertTableEquals(r1, r2);
}

{
final Table r1 = table.where("X <= Y");
final Table r2 = table.where("Y >= X");
Assert.equals(r1.getRowSet(), "r1.getRowSet()", RowSetFactory.flat(2));
assertTableEquals(r1, r2);
}
}

@Test
@Ignore
public void testEnsureColumnArraysTakePrecedence() {
// TODO: column arrays aren't well supported in match arrays and this example's where filter fails to compile
final Table table = emptyTable(10).update("X=i", "Y=new int[]{1, 5, 9}");
ExecutionContext.getContext().getQueryScope().putParam("Y_", new int[] {0, 4, 8});

final Table result = table.where("X == Y_[1]");
Assert.equals(result.getRowSet(), "result.getRowSet()", RowSetFactory.fromKeys(5));

// check that the mirror matches the expected result
final Table mResult = table.where("Y_[1] == X");
assertTableEquals(result, mResult);
}

@Test
public void testIntToByteCoercion() {
final Table table = emptyTable(11).update("X = ii % 2 == 0 ? (byte) ii : null");
final Class<Object> colType = table.getDefinition().getColumn("X").getDataType();
Assert.eq(colType, "colType", byte.class);

ExecutionContext.getContext().getQueryScope().putParam("val_null", QueryConstants.NULL_INT);
ExecutionContext.getContext().getQueryScope().putParam("val_5", 5);

final Table null_result = table.where("X == val_null");
final Table range_result = table.where("X >= val_5");
Assert.eq(null_result.size(), "null_result.size()", 5);
Assert.eq(range_result.size(), "range_result.size()", 3);
}

@Test
public void testIntToShortCoercion() {
final Table table = emptyTable(11).update("X= ii % 2 == 0 ? (short) ii : null");
final Class<Object> colType = table.getDefinition().getColumn("X").getDataType();
Assert.eq(colType, "colType", short.class);

ExecutionContext.getContext().getQueryScope().putParam("val_null", QueryConstants.NULL_INT);
ExecutionContext.getContext().getQueryScope().putParam("val_5", 5);

final Table null_result = table.where("X == val_null");
final Table range_result = table.where("X >= val_5");
Assert.eq(null_result.size(), "null_result.size()", 5);
Assert.eq(range_result.size(), "range_result.size()", 3);
}

@Test
public void testLongToIntCoercion() {
final Table table = emptyTable(11).update("X= ii % 2 == 0 ? (int) ii : null");
final Class<Object> colType = table.getDefinition().getColumn("X").getDataType();
Assert.eq(colType, "colType", int.class);

ExecutionContext.getContext().getQueryScope().putParam("val_null", QueryConstants.NULL_LONG);
ExecutionContext.getContext().getQueryScope().putParam("val_5", 5L);

final Table null_result = table.where("X == val_null");
final Table range_result = table.where("X >= val_5");
Assert.eq(null_result.size(), "null_result.size()", 5);
Assert.eq(range_result.size(), "range_result.size()", 3);
}

@Test
public void testIntToLongCoercion() {
final Table table = emptyTable(11).update("X= ii % 2 == 0 ? ii : null");
final Class<Object> colType = table.getDefinition().getColumn("X").getDataType();
Assert.eq(colType, "colType", long.class);

ExecutionContext.getContext().getQueryScope().putParam("val_null", QueryConstants.NULL_INT);
ExecutionContext.getContext().getQueryScope().putParam("val_5", 5);

final Table null_result = table.where("X == val_null");
final Table range_result = table.where("X >= val_5");
Assert.eq(null_result.size(), "null_result.size()", 5);
Assert.eq(range_result.size(), "range_result.size()", 3);
}

@Test
public void testIntToFloatCoercion() {
final Table table = emptyTable(11).update("X= ii % 2 == 0 ? (float) ii : null");
final Class<Object> colType = table.getDefinition().getColumn("X").getDataType();
Assert.eq(colType, "colType", float.class);

ExecutionContext.getContext().getQueryScope().putParam("val_null", QueryConstants.NULL_INT);
ExecutionContext.getContext().getQueryScope().putParam("val_5", 5);

final Table null_result = table.where("X == val_null");
final Table range_result = table.where("X >= val_5");
Assert.eq(null_result.size(), "null_result.size()", 5);
Assert.eq(range_result.size(), "range_result.size()", 3);
}

@Test
public void testIntToDoubleCoercion() {
final Table table = emptyTable(11).update("X= ii % 2 == 0 ? (double) ii : null");
final Class<Object> colType = table.getDefinition().getColumn("X").getDataType();
Assert.eq(colType, "colType", double.class);

ExecutionContext.getContext().getQueryScope().putParam("val_null", QueryConstants.NULL_INT);
ExecutionContext.getContext().getQueryScope().putParam("val_5", 5);

final Table null_result = table.where("X == val_null");
final Table range_result = table.where("X >= val_5");
Assert.eq(null_result.size(), "null_result.size()", 5);
Assert.eq(range_result.size(), "range_result.size()", 3);
}
}
Loading