use of com.amazonaws.athena.connector.lambda.data.writers.extractors.DateMilliExtractor in project aws-athena-query-federation by awslabs.
the class ElasticsearchTypeUtilsTest method testField.
/**
* Uses the correct field extractor to extract values from a document.
* @param mapping is the metadata definitions of the document being processed.
* @param document contains the values to be extracted.
* @return a map of the field names and their associated values extracted from the document.
* @throws Exception
*/
private Map<String, Object> testField(Schema mapping, Map<String, Object> document) throws Exception {
Map<String, Object> results = new HashMap<>();
for (Field field : mapping.getFields()) {
Extractor extractor = typeUtils.makeExtractor(field);
if (extractor instanceof VarCharExtractor) {
NullableVarCharHolder holder = new NullableVarCharHolder();
((VarCharExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof BigIntExtractor) {
NullableBigIntHolder holder = new NullableBigIntHolder();
((BigIntExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof IntExtractor) {
NullableIntHolder holder = new NullableIntHolder();
((IntExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof SmallIntExtractor) {
NullableSmallIntHolder holder = new NullableSmallIntHolder();
((SmallIntExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof TinyIntExtractor) {
NullableTinyIntHolder holder = new NullableTinyIntHolder();
((TinyIntExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof Float8Extractor) {
NullableFloat8Holder holder = new NullableFloat8Holder();
((Float8Extractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof Float4Extractor) {
NullableFloat4Holder holder = new NullableFloat4Holder();
((Float4Extractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof DateMilliExtractor) {
NullableDateMilliHolder holder = new NullableDateMilliHolder();
((DateMilliExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
} else if (extractor instanceof BitExtractor) {
NullableBitHolder holder = new NullableBitHolder();
((BitExtractor) extractor).extract(document, holder);
assertEquals("Could not extract value for: " + field.getName(), 1, holder.isSet);
results.put(field.getName(), holder.value);
}
}
return results;
}
use of com.amazonaws.athena.connector.lambda.data.writers.extractors.DateMilliExtractor in project aws-athena-query-federation by awslabs.
the class GeneratedRowWriter method makeFieldWriter.
private FieldWriter makeFieldWriter(FieldVector vector) {
Field field = vector.getField();
String fieldName = field.getName();
Types.MinorType fieldType = Types.getMinorTypeForArrowType(field.getType());
Extractor extractor = extractors.get(fieldName);
ConstraintProjector constraint = constraints.get(fieldName);
FieldWriterFactory factory = fieldWriterFactories.get(fieldName);
if (factory != null) {
return factory.create(vector, extractor, constraint);
}
if (extractor == null) {
throw new IllegalStateException("Missing extractor for field[" + fieldName + "]");
}
switch(fieldType) {
case INT:
return new IntFieldWriter((IntExtractor) extractor, (IntVector) vector, constraint);
case BIGINT:
return new BigIntFieldWriter((BigIntExtractor) extractor, (BigIntVector) vector, constraint);
case DATEMILLI:
return new DateMilliFieldWriter((DateMilliExtractor) extractor, (DateMilliVector) vector, constraint);
case DATEDAY:
return new DateDayFieldWriter((DateDayExtractor) extractor, (DateDayVector) vector, constraint);
case TINYINT:
return new TinyIntFieldWriter((TinyIntExtractor) extractor, (TinyIntVector) vector, constraint);
case SMALLINT:
return new SmallIntFieldWriter((SmallIntExtractor) extractor, (SmallIntVector) vector, constraint);
case FLOAT4:
return new Float4FieldWriter((Float4Extractor) extractor, (Float4Vector) vector, constraint);
case FLOAT8:
return new Float8FieldWriter((Float8Extractor) extractor, (Float8Vector) vector, constraint);
case DECIMAL:
return new DecimalFieldWriter((DecimalExtractor) extractor, (DecimalVector) vector, constraint);
case BIT:
return new BitFieldWriter((BitExtractor) extractor, (BitVector) vector, constraint);
case VARCHAR:
return new VarCharFieldWriter((VarCharExtractor) extractor, (VarCharVector) vector, constraint);
case VARBINARY:
return new VarBinaryFieldWriter((VarBinaryExtractor) extractor, (VarBinaryVector) vector, constraint);
default:
throw new RuntimeException(fieldType + " is not supported");
}
}
use of com.amazonaws.athena.connector.lambda.data.writers.extractors.DateMilliExtractor in project aws-athena-query-federation by awslabs.
the class ExampleRecordHandler method makeExtractor.
/**
* Creates an Extractor for the given field. In this example the extractor just creates some random data.
*/
private Extractor makeExtractor(Field field, RowContext rowContext) {
Types.MinorType fieldType = Types.getMinorTypeForArrowType(field.getType());
// they need to match the split otherwise filtering will brake in unexpected ways.
if (field.getName().equals("year")) {
return (IntExtractor) (Object context, NullableIntHolder dst) -> {
dst.isSet = 1;
dst.value = rowContext.getYear();
};
} else if (field.getName().equals("month")) {
return (IntExtractor) (Object context, NullableIntHolder dst) -> {
dst.isSet = 1;
dst.value = rowContext.getMonth();
};
} else if (field.getName().equals("day")) {
return (IntExtractor) (Object context, NullableIntHolder dst) -> {
dst.isSet = 1;
dst.value = rowContext.getDay();
};
}
switch(fieldType) {
case INT:
return (IntExtractor) (Object context, NullableIntHolder dst) -> {
dst.isSet = 1;
dst.value = ((RowContext) context).seed * (((RowContext) context).negative ? -1 : 1);
};
case DATEMILLI:
return (DateMilliExtractor) (Object context, NullableDateMilliHolder dst) -> {
dst.isSet = 1;
dst.value = ((RowContext) context).seed * (((RowContext) context).negative ? -1 : 1);
};
case DATEDAY:
return (DateDayExtractor) (Object context, NullableDateDayHolder dst) -> {
dst.isSet = 1;
dst.value = ((RowContext) context).seed * (((RowContext) context).negative ? -1 : 1);
};
case TINYINT:
return (TinyIntExtractor) (Object context, NullableTinyIntHolder dst) -> {
dst.isSet = 1;
dst.value = (byte) ((((RowContext) context).seed % 4) * (((RowContext) context).negative ? -1 : 1));
};
case SMALLINT:
return (SmallIntExtractor) (Object context, NullableSmallIntHolder dst) -> {
dst.isSet = 1;
dst.value = (short) ((((RowContext) context).seed % 4) * (((RowContext) context).negative ? -1 : 1));
};
case FLOAT4:
return (Float4Extractor) (Object context, NullableFloat4Holder dst) -> {
dst.isSet = 1;
dst.value = ((float) ((RowContext) context).seed) * 1.1f * (((RowContext) context).negative ? -1f : 1f);
};
case FLOAT8:
return (Float8Extractor) (Object context, NullableFloat8Holder dst) -> {
dst.isSet = 1;
dst.value = ((double) ((RowContext) context).seed) * 1.1D;
};
case DECIMAL:
return (DecimalExtractor) (Object context, NullableDecimalHolder dst) -> {
dst.isSet = 1;
double d8Val = ((RowContext) context).seed * 1.1D * (((RowContext) context).negative ? -1d : 1d);
BigDecimal bdVal = new BigDecimal(d8Val);
dst.value = bdVal.setScale(((ArrowType.Decimal) field.getType()).getScale(), RoundingMode.HALF_UP);
};
case BIT:
return (BitExtractor) (Object context, NullableBitHolder dst) -> {
dst.isSet = 1;
dst.value = ((RowContext) context).seed % 2;
};
case BIGINT:
return (BigIntExtractor) (Object context, NullableBigIntHolder dst) -> {
dst.isSet = 1;
dst.value = ((RowContext) context).seed * 1L * (((RowContext) context).negative ? -1 : 1);
};
case VARCHAR:
return (VarCharExtractor) (Object context, NullableVarCharHolder dst) -> {
dst.isSet = 1;
dst.value = "VarChar" + ((RowContext) context).seed;
};
case VARBINARY:
return (VarBinaryExtractor) (Object context, NullableVarBinaryHolder dst) -> {
dst.isSet = 1;
dst.value = ("VarChar" + ((RowContext) context).seed).getBytes(Charsets.UTF_8);
};
default:
return null;
}
}
use of com.amazonaws.athena.connector.lambda.data.writers.extractors.DateMilliExtractor in project aws-athena-query-federation by awslabs.
the class ElasticsearchTypeUtils method makeDateMilliExtractor.
/**
* Create an DATEMILLI field extractor to extract a date value from a Document. The Document value can be returned
* as a numeric value, a String, or a List. For the latter, extract the first element only.
* For dates extracted as a string, the ISO_ZONED_DATE_TIME format will be attempted first, followed by the
* ISO_LOCAL_DATE_TIME format if the previous one fails. Examples of formats that will work:
* 1) "2020-05-18T10:15:30.123456789"
* 2) "2020-05-15T06:50:01.123Z"
* 3) "2020-05-15T06:49:30.123-05:00".
* Numeric dates values should be a long numeric value representing epoch milliseconds (e.g. 1589525370001)
* Nanoseconds will be rounded to the nearest millisecond.
* @param field is used to determine which extractor to generate based on the field type.
* @return a field extractor.
*/
private Extractor makeDateMilliExtractor(Field field) {
return (DateMilliExtractor) (Object context, NullableDateMilliHolder dst) -> {
Object fieldValue = ((Map) context).get(field.getName());
dst.isSet = 1;
if (fieldValue instanceof String) {
try {
long epochSeconds;
double nanoSeconds;
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse((String) fieldValue, DateTimeFormatter.ISO_ZONED_DATE_TIME.withResolverStyle(ResolverStyle.SMART));
epochSeconds = zonedDateTime.toEpochSecond();
nanoSeconds = zonedDateTime.getNano();
} catch (DateTimeParseException error) {
LocalDateTime localDateTime = LocalDateTime.parse((String) fieldValue, DateTimeFormatter.ISO_LOCAL_DATE_TIME.withResolverStyle(ResolverStyle.SMART));
epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC);
nanoSeconds = localDateTime.getNano();
}
dst.value = epochSeconds * 1000 + Math.round(nanoSeconds / 1000000);
} catch (DateTimeParseException error) {
logger.warn("Error parsing localDateTime: {}.", error.getMessage());
dst.isSet = 0;
}
} else if (fieldValue instanceof Number) {
dst.value = ((Number) fieldValue).longValue();
} else if (fieldValue instanceof List) {
Object value = ((List) fieldValue).get(0);
if (value instanceof String) {
try {
long epochSeconds;
double nanoSeconds;
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse((String) value, DateTimeFormatter.ISO_ZONED_DATE_TIME.withZone(ZoneId.of("UTC")).withResolverStyle(ResolverStyle.SMART));
epochSeconds = zonedDateTime.toEpochSecond();
nanoSeconds = zonedDateTime.getNano();
} catch (DateTimeParseException error) {
LocalDateTime localDateTime = LocalDateTime.parse((String) value, DateTimeFormatter.ISO_LOCAL_DATE_TIME.withResolverStyle(ResolverStyle.SMART));
epochSeconds = localDateTime.toEpochSecond(ZoneOffset.UTC);
nanoSeconds = localDateTime.getNano();
}
dst.value = epochSeconds * 1000 + Math.round(nanoSeconds / 1000000);
} catch (DateTimeParseException error) {
logger.warn("Error parsing localDateTime: {}.", error.getMessage());
dst.isSet = 0;
}
} else if (value instanceof Number) {
dst.value = ((Number) value).longValue();
} else {
dst.isSet = 0;
}
} else {
dst.isSet = 0;
}
};
}
Aggregations