in athena-jdbc/src/main/java/com/amazonaws/athena/connectors/jdbc/manager/JdbcSplitQueryBuilder.java [85:174]
public PreparedStatement buildSql(
final Connection jdbcConnection,
final String catalog,
final String schema,
final String table,
final Schema tableSchema,
final Constraints constraints,
final Split split)
throws SQLException
{
StringBuilder sql = new StringBuilder();
String columnNames = tableSchema.getFields().stream()
.map(Field::getName)
.filter(c -> !split.getProperties().containsKey(c))
.map(this::quote)
.collect(Collectors.joining(", "));
sql.append("SELECT ");
sql.append(columnNames);
if (columnNames.isEmpty()) {
sql.append("null");
}
sql.append(getFromClauseWithSplit(catalog, schema, table, split));
List<TypeAndValue> accumulator = new ArrayList<>();
List<String> clauses = toConjuncts(tableSchema.getFields(), constraints, accumulator, split.getProperties());
clauses.addAll(getPartitionWhereClauses(split));
if (!clauses.isEmpty()) {
sql.append(" WHERE ")
.append(Joiner.on(" AND ").join(clauses));
}
LOGGER.info("Generated SQL : {}", sql.toString());
PreparedStatement statement = jdbcConnection.prepareStatement(sql.toString());
// TODO all types, converts Arrow values to JDBC.
for (int i = 0; i < accumulator.size(); i++) {
TypeAndValue typeAndValue = accumulator.get(i);
Types.MinorType minorTypeForArrowType = Types.getMinorTypeForArrowType(typeAndValue.getType());
switch (minorTypeForArrowType) {
case BIGINT:
statement.setLong(i + 1, (long) typeAndValue.getValue());
break;
case INT:
statement.setInt(i + 1, ((Number) typeAndValue.getValue()).intValue());
break;
case SMALLINT:
statement.setShort(i + 1, ((Number) typeAndValue.getValue()).shortValue());
break;
case TINYINT:
statement.setByte(i + 1, ((Number) typeAndValue.getValue()).byteValue());
break;
case FLOAT8:
statement.setDouble(i + 1, (double) typeAndValue.getValue());
break;
case FLOAT4:
statement.setFloat(i + 1, (float) typeAndValue.getValue());
break;
case BIT:
statement.setBoolean(i + 1, (boolean) typeAndValue.getValue());
break;
case DATEDAY:
statement.setDate(i + 1,
new Date(TimeUnit.DAYS.toMillis(((Number) typeAndValue.getValue()).longValue())));
break;
case DATEMILLI:
LocalDateTime timestamp = ((LocalDateTime) typeAndValue.getValue());
statement.setTimestamp(i + 1, new Timestamp(timestamp.toInstant(ZoneOffset.UTC).toEpochMilli()));
break;
case VARCHAR:
statement.setString(i + 1, String.valueOf(typeAndValue.getValue()));
break;
case VARBINARY:
statement.setBytes(i + 1, (byte[]) typeAndValue.getValue());
break;
case DECIMAL:
statement.setBigDecimal(i + 1, (BigDecimal) typeAndValue.getValue());
break;
default:
throw new UnsupportedOperationException(String.format("Can't handle type: %s, %s", typeAndValue.getType(), minorTypeForArrowType));
}
}
return statement;
}