use of com.amazonaws.athena.connector.lambda.domain.predicate.Range in project aws-athena-query-federation by awslabs.
the class JdbcSplitQueryBuilder method toPredicate.
private String toPredicate(String columnName, ValueSet valueSet, ArrowType type, List<TypeAndValue> accumulator) {
List<String> disjuncts = new ArrayList<>();
List<Object> singleValues = new ArrayList<>();
if (valueSet instanceof SortedRangeSet) {
if (valueSet.isNone() && valueSet.isNullAllowed()) {
return String.format("(%s IS NULL)", quote(columnName));
}
if (valueSet.isNullAllowed()) {
disjuncts.add(String.format("(%s IS NULL)", quote(columnName)));
}
Range rangeSpan = ((SortedRangeSet) valueSet).getSpan();
if (!valueSet.isNullAllowed() && rangeSpan.getLow().isLowerUnbounded() && rangeSpan.getHigh().isUpperUnbounded()) {
return String.format("(%s IS NOT NULL)", quote(columnName));
}
for (Range range : valueSet.getRanges().getOrderedRanges()) {
if (range.isSingleValue()) {
singleValues.add(range.getLow().getValue());
} else {
List<String> rangeConjuncts = new ArrayList<>();
if (!range.getLow().isLowerUnbounded()) {
switch(range.getLow().getBound()) {
case ABOVE:
rangeConjuncts.add(toPredicate(columnName, ">", range.getLow().getValue(), type, accumulator));
break;
case EXACTLY:
rangeConjuncts.add(toPredicate(columnName, ">=", range.getLow().getValue(), type, accumulator));
break;
case BELOW:
throw new IllegalArgumentException("Low marker should never use BELOW bound");
default:
throw new AssertionError("Unhandled bound: " + range.getLow().getBound());
}
}
if (!range.getHigh().isUpperUnbounded()) {
switch(range.getHigh().getBound()) {
case ABOVE:
throw new IllegalArgumentException("High marker should never use ABOVE bound");
case EXACTLY:
rangeConjuncts.add(toPredicate(columnName, "<=", range.getHigh().getValue(), type, accumulator));
break;
case BELOW:
rangeConjuncts.add(toPredicate(columnName, "<", range.getHigh().getValue(), type, accumulator));
break;
default:
throw new AssertionError("Unhandled bound: " + range.getHigh().getBound());
}
}
// If rangeConjuncts is null, then the range was ALL, which should already have been checked for
Preconditions.checkState(!rangeConjuncts.isEmpty());
disjuncts.add("(" + Joiner.on(" AND ").join(rangeConjuncts) + ")");
}
}
// Add back all of the possible single values either as an equality or an IN predicate
if (singleValues.size() == 1) {
disjuncts.add(toPredicate(columnName, "=", Iterables.getOnlyElement(singleValues), type, accumulator));
} else if (singleValues.size() > 1) {
for (Object value : singleValues) {
accumulator.add(new TypeAndValue(type, value));
}
String values = Joiner.on(",").join(Collections.nCopies(singleValues.size(), "?"));
disjuncts.add(quote(columnName) + " IN (" + values + ")");
}
}
return "(" + Joiner.on(" OR ").join(disjuncts) + ")";
}
use of com.amazonaws.athena.connector.lambda.domain.predicate.Range in project aws-athena-query-federation by awslabs.
the class HiveRecordHandlerTest method buildSplitSql.
@Test
public void buildSplitSql() throws SQLException {
TableName tableName = new TableName("testSchema", "testTable");
SchemaBuilder schemaBuilder = SchemaBuilder.newBuilder();
schemaBuilder.addField(FieldBuilder.newBuilder("testCol1", Types.MinorType.INT.getType()).build());
schemaBuilder.addField(FieldBuilder.newBuilder("testCol2", Types.MinorType.DATEDAY.getType()).build());
schemaBuilder.addField(FieldBuilder.newBuilder("testCol3", Types.MinorType.DATEMILLI.getType()).build());
schemaBuilder.addField(FieldBuilder.newBuilder("testCol4", Types.MinorType.VARBINARY.getType()).build());
schemaBuilder.addField(FieldBuilder.newBuilder("partition", Types.MinorType.VARCHAR.getType()).build());
Schema schema = schemaBuilder.build();
Split split = Mockito.mock(Split.class);
Mockito.when(split.getProperties()).thenReturn(Collections.singletonMap("partition", "p0"));
Mockito.when(split.getProperty(Mockito.eq("partition"))).thenReturn("p0");
Range range1a = Mockito.mock(Range.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(range1a.isSingleValue()).thenReturn(true);
Mockito.when(range1a.getLow().getValue()).thenReturn(1);
Range range1b = Mockito.mock(Range.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(range1b.isSingleValue()).thenReturn(true);
Mockito.when(range1b.getLow().getValue()).thenReturn(2);
ValueSet valueSet1 = Mockito.mock(SortedRangeSet.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(valueSet1.getRanges().getOrderedRanges()).thenReturn(ImmutableList.of(range1a, range1b));
final long dateDays = TimeUnit.DAYS.toDays(Date.valueOf("2020-01-05").getTime());
ValueSet valueSet2 = getSingleValueSet(dateDays);
Constraints constraints = Mockito.mock(Constraints.class);
Mockito.when(constraints.getSummary()).thenReturn(new ImmutableMap.Builder<String, ValueSet>().put("testCol2", valueSet2).build());
PreparedStatement expectedPreparedStatement = Mockito.mock(PreparedStatement.class);
Mockito.when(this.connection.prepareStatement(Mockito.anyString())).thenReturn(expectedPreparedStatement);
PreparedStatement preparedStatement = this.hiveRecordHandler.buildSplitSql(this.connection, "testCatalogName", tableName, schema, constraints, split);
Assert.assertEquals(expectedPreparedStatement, preparedStatement);
}
use of com.amazonaws.athena.connector.lambda.domain.predicate.Range in project aws-athena-query-federation by awslabs.
the class HiveRecordHandlerTest method getSingleValueSet.
private ValueSet getSingleValueSet(Object value) {
Range range = Mockito.mock(Range.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(range.isSingleValue()).thenReturn(true);
Mockito.when(range.getLow().getValue()).thenReturn(value);
ValueSet valueSet = Mockito.mock(SortedRangeSet.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(valueSet.getRanges().getOrderedRanges()).thenReturn(Collections.singletonList(range));
return valueSet;
}
use of com.amazonaws.athena.connector.lambda.domain.predicate.Range in project aws-athena-query-federation by awslabs.
the class PropertyGraphHandler method getQueryPartForContraintsMap.
/**
* Used to generate Gremlin Query part for Constraint Map
*
* @param traversal Gremlin Traversal, traversal is updated based on constraints
* map
* @param hasMap Constraint Hash Map
*
* @return A Gremlin Query Part equivalent to Contraint.
*/
public GraphTraversal getQueryPartForContraintsMap(GraphTraversal traversal, final ReadRecordsRequest recordsRequest) {
final Map<String, ValueSet> hashMap = recordsRequest.getConstraints().getSummary();
if (hashMap.size() == 0) {
return traversal;
}
logger.info("readWithContraint: Constaints Map " + hashMap.toString());
final Set<String> setOfkeys = (Set<String>) (hashMap.keySet());
for (final String key : setOfkeys) {
if (hashMap.get(key) instanceof SortedRangeSet) {
final List<Range> ranges = ((SortedRangeSet) hashMap.get(key)).getOrderedRanges();
for (final Range range : ranges) {
if (!range.getLow().isNullValue() && !range.getHigh().isNullValue()) {
if (range.getLow().getValue().toString().equals(range.getHigh().getValue().toString())) {
traversal = GremlinQueryPreProcessor.generateGremlinQueryPart(traversal, key, range.getLow().getValue().toString(), range.getType(), range.getLow().getBound(), GremlinQueryPreProcessor.Operator.EQUALTO);
break;
}
}
if (!range.getLow().isNullValue()) {
traversal = GremlinQueryPreProcessor.generateGremlinQueryPart(traversal, key, range.getLow().getValue().toString(), range.getType(), range.getLow().getBound(), GremlinQueryPreProcessor.Operator.GREATERTHAN);
}
if (!range.getHigh().isNullValue()) {
traversal = GremlinQueryPreProcessor.generateGremlinQueryPart(traversal, key, range.getHigh().getValue().toString(), range.getType(), range.getHigh().getBound(), GremlinQueryPreProcessor.Operator.LESSTHAN);
}
}
}
if (hashMap.get(key) instanceof EquatableValueSet) {
final EquatableValueSet valueSet = ((EquatableValueSet) hashMap.get(key));
if (valueSet.isWhiteList()) {
traversal = GremlinQueryPreProcessor.generateGremlinQueryPart(traversal, key, valueSet.getValue(0).toString(), valueSet.getType(), null, GremlinQueryPreProcessor.Operator.EQUALTO);
} else {
traversal = GremlinQueryPreProcessor.generateGremlinQueryPart(traversal, key, valueSet.getValue(0).toString(), valueSet.getType(), null, GremlinQueryPreProcessor.Operator.NOTEQUALTO);
}
}
}
return traversal;
}
use of com.amazonaws.athena.connector.lambda.domain.predicate.Range in project aws-athena-query-federation by awslabs.
the class MySqlRecordHandlerTest method getRangeSet.
private ValueSet getRangeSet(Marker.Bound lowerBound, Object lowerValue, Marker.Bound upperBound, Object upperValue) {
Range range = Mockito.mock(Range.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(range.isSingleValue()).thenReturn(false);
Mockito.when(range.getLow().getBound()).thenReturn(lowerBound);
Mockito.when(range.getLow().getValue()).thenReturn(lowerValue);
Mockito.when(range.getHigh().getBound()).thenReturn(upperBound);
Mockito.when(range.getHigh().getValue()).thenReturn(upperValue);
ValueSet valueSet = Mockito.mock(SortedRangeSet.class, Mockito.RETURNS_DEEP_STUBS);
Mockito.when(valueSet.getRanges().getOrderedRanges()).thenReturn(Collections.singletonList(range));
return valueSet;
}
Aggregations