use of com.facebook.presto.sql.tree.SingleColumn in project presto by prestodb.
the class QueryRewriter method rewriteNonStorableColumns.
private Query rewriteNonStorableColumns(Query query, ResultSetMetaData metadata) {
// Skip if all columns are storable
List<Type> columnTypes = getColumnTypes(typeManager, metadata);
if (columnTypes.stream().noneMatch(type -> getColumnTypeRewrite(type).isPresent())) {
return query;
}
// Cannot handle SELECT query with top-level SetOperation
if (!(query.getQueryBody() instanceof QuerySpecification)) {
return query;
}
QuerySpecification querySpecification = (QuerySpecification) query.getQueryBody();
List<SelectItem> selectItems = querySpecification.getSelect().getSelectItems();
// Cannot handle SELECT *
if (selectItems.stream().anyMatch(AllColumns.class::isInstance)) {
return query;
}
List<SelectItem> newItems = new ArrayList<>();
checkState(selectItems.size() == columnTypes.size(), "SelectItem count (%s) mismatches column count (%s)", selectItems.size(), columnTypes.size());
for (int i = 0; i < selectItems.size(); i++) {
SingleColumn singleColumn = (SingleColumn) selectItems.get(i);
Optional<Type> columnTypeRewrite = getColumnTypeRewrite(columnTypes.get(i));
if (columnTypeRewrite.isPresent()) {
newItems.add(new SingleColumn(new Cast(singleColumn.getExpression(), columnTypeRewrite.get().getTypeSignature().toString()), singleColumn.getAlias()));
} else {
newItems.add(singleColumn);
}
}
return new Query(query.getWith(), new QuerySpecification(new Select(querySpecification.getSelect().isDistinct(), newItems), querySpecification.getFrom(), querySpecification.getWhere(), querySpecification.getGroupBy(), querySpecification.getHaving(), querySpecification.getOrderBy(), Optional.empty(), querySpecification.getLimit()), query.getOrderBy(), Optional.empty(), query.getLimit());
}
use of com.facebook.presto.sql.tree.SingleColumn in project presto by prestodb.
the class LimitQueryDeterminismAnalyzer method populateSelectItems.
/**
* To check whether all ORDER BY columns are matching between the n-th and the (n+1)-th row, we
* may need to project additional columns. Takes in the list of SelectItems of the original query
* and append additional SelectItems to the list.
*
* @param selectItems A list of {@link SelectItem} of the original query
* @param orderBy ORDER BY clause
* @return the list of column keys to locate ORDER BY columns in the query result
*/
private List<ColumnNameOrIndex> populateSelectItems(List<SelectItem> selectItems, OrderBy orderBy) {
Set<String> aliases = selectItems.stream().filter(SingleColumn.class::isInstance).map(SingleColumn.class::cast).map(SingleColumn::getAlias).filter(Optional::isPresent).map(Optional::get).map(Identifier::getValue).collect(toImmutableSet());
ImmutableList.Builder<ColumnNameOrIndex> orderByKeys = ImmutableList.builder();
for (int i = 0; i < orderBy.getSortItems().size(); i++) {
Expression sortKey = orderBy.getSortItems().get(i).getSortKey();
if (sortKey instanceof LongLiteral) {
// If sortKey is an long literal, it can be referenced by column index.
orderByKeys.add(ColumnNameOrIndex.forIndex(toIntExact(((LongLiteral) sortKey).getValue()) - 1));
} else if (sortKey instanceof Identifier && aliases.contains(((Identifier) sortKey).getValue())) {
// If sortKey is an identifier, it can either be an alias or a column name.
// It is impossible for two columns to have the same alias as sortKey, since otherwise a SYNTAX_ERROR will be thrown due to sortKey being ambiguous.
// It is possible that sortKey is both an alias and a column name. In that case, sortKey references the aliased column.
orderByKeys.add(ColumnNameOrIndex.forName(((Identifier) sortKey).getValue()));
} else {
// If the sortKey is non-alias identifier, select the sortKey column, since it might not be selected or it might be aliased.
// If the sortKey is not an identifier, select the sortKey column.
String columnName = "$$sort_key$$" + i;
selectItems.add(new SingleColumn(sortKey, delimitedIdentifier(columnName)));
orderByKeys.add(ColumnNameOrIndex.forName(columnName));
}
}
return orderByKeys.build();
}
use of com.facebook.presto.sql.tree.SingleColumn in project presto by prestodb.
the class MapColumnValidator method generateChecksumColumns.
@Override
public List<SingleColumn> generateChecksumColumns(Column column) {
checkArgument(column.getType() instanceof MapType, "Expect MapType, found %s", column.getType().getDisplayName());
Type keyType = ((MapType) column.getType()).getKeyType();
Type valueType = ((MapType) column.getType()).getValueType();
Expression checksum = functionCall("checksum", column.getExpression());
Expression keysChecksum = generateArrayChecksum(functionCall("map_keys", column.getExpression()), new ArrayType(keyType));
Expression valuesChecksum = generateArrayChecksum(functionCall("map_values", column.getExpression()), new ArrayType(valueType));
Expression mapCardinalityChecksum = functionCall("checksum", functionCall("cardinality", column.getExpression()));
Expression mapCardinalitySum = new CoalesceExpression(functionCall("sum", functionCall("cardinality", column.getExpression())), new LongLiteral("0"));
return ImmutableList.of(new SingleColumn(checksum, Optional.of(delimitedIdentifier(getChecksumColumnAlias(column)))), new SingleColumn(keysChecksum, Optional.of(delimitedIdentifier(getKeysChecksumColumnAlias(column)))), new SingleColumn(valuesChecksum, Optional.of(delimitedIdentifier(getValuesChecksumColumnAlias(column)))), new SingleColumn(mapCardinalityChecksum, Optional.of(delimitedIdentifier(getCardinalityChecksumColumnAlias(column)))), new SingleColumn(mapCardinalitySum, Optional.of(delimitedIdentifier(getCardinalitySumColumnAlias(column)))));
}
Aggregations