use of com.facebook.presto.sql.tree.Identifier in project presto by prestodb.
the class TestSqlParser method testLambda.
@Test
public void testLambda() {
assertExpression("() -> x", new LambdaExpression(ImmutableList.of(), new Identifier("x")));
assertExpression("x -> sin(x)", new LambdaExpression(ImmutableList.of(new LambdaArgumentDeclaration(identifier("x"))), new FunctionCall(QualifiedName.of("sin"), ImmutableList.of(new Identifier("x")))));
assertExpression("(x, y) -> mod(x, y)", new LambdaExpression(ImmutableList.of(new LambdaArgumentDeclaration(identifier("x")), new LambdaArgumentDeclaration(identifier("y"))), new FunctionCall(QualifiedName.of("mod"), ImmutableList.of(new Identifier("x"), new Identifier("y")))));
}
use of com.facebook.presto.sql.tree.Identifier in project presto by prestodb.
the class RelationPlanner method planJoinUsing.
private RelationPlan planJoinUsing(Join node, RelationPlan left, RelationPlan right) {
/* Given: l JOIN r USING (k1, ..., kn)
produces:
- project
coalesce(l.k1, r.k1)
...,
coalesce(l.kn, r.kn)
l.v1,
...,
l.vn,
r.v1,
...,
r.vn
- join (l.k1 = r.k1 and ... l.kn = r.kn)
- project
cast(l.k1 as commonType(l.k1, r.k1))
...
- project
cast(rl.k1 as commonType(l.k1, r.k1))
If casts are redundant (due to column type and common type being equal),
they will be removed by optimization passes.
*/
List<Identifier> joinColumns = ((JoinUsing) node.getCriteria().get()).getColumns();
Analysis.JoinUsingAnalysis joinAnalysis = analysis.getJoinUsing(node);
ImmutableList.Builder<JoinNode.EquiJoinClause> clauses = ImmutableList.builder();
Map<Identifier, VariableReferenceExpression> leftJoinColumns = new HashMap<>();
Map<Identifier, VariableReferenceExpression> rightJoinColumns = new HashMap<>();
Assignments.Builder leftCoercions = Assignments.builder();
Assignments.Builder rightCoercions = Assignments.builder();
leftCoercions.putAll(identitiesAsSymbolReferences(left.getRoot().getOutputVariables()));
rightCoercions.putAll(identitiesAsSymbolReferences(right.getRoot().getOutputVariables()));
for (int i = 0; i < joinColumns.size(); i++) {
Identifier identifier = joinColumns.get(i);
Type type = analysis.getType(identifier);
// compute the coercion for the field on the left to the common supertype of left & right
VariableReferenceExpression leftOutput = variableAllocator.newVariable(identifier, type);
int leftField = joinAnalysis.getLeftJoinFields().get(i);
leftCoercions.put(leftOutput, castToRowExpression(new Cast(identifier.getLocation(), createSymbolReference(left.getVariable(leftField)), type.getTypeSignature().toString(), false, metadata.getFunctionAndTypeManager().isTypeOnlyCoercion(left.getDescriptor().getFieldByIndex(leftField).getType(), type))));
leftJoinColumns.put(identifier, leftOutput);
// compute the coercion for the field on the right to the common supertype of left & right
VariableReferenceExpression rightOutput = variableAllocator.newVariable(identifier, type);
int rightField = joinAnalysis.getRightJoinFields().get(i);
rightCoercions.put(rightOutput, castToRowExpression(new Cast(identifier.getLocation(), createSymbolReference(right.getVariable(rightField)), type.getTypeSignature().toString(), false, metadata.getFunctionAndTypeManager().isTypeOnlyCoercion(right.getDescriptor().getFieldByIndex(rightField).getType(), type))));
rightJoinColumns.put(identifier, rightOutput);
clauses.add(new JoinNode.EquiJoinClause(leftOutput, rightOutput));
}
ProjectNode leftCoercion = new ProjectNode(idAllocator.getNextId(), left.getRoot(), leftCoercions.build());
ProjectNode rightCoercion = new ProjectNode(idAllocator.getNextId(), right.getRoot(), rightCoercions.build());
JoinNode join = new JoinNode(getSourceLocation(node), idAllocator.getNextId(), JoinNodeUtils.typeConvert(node.getType()), leftCoercion, rightCoercion, clauses.build(), ImmutableList.<VariableReferenceExpression>builder().addAll(leftCoercion.getOutputVariables()).addAll(rightCoercion.getOutputVariables()).build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of());
// Add a projection to produce the outputs of the columns in the USING clause,
// which are defined as coalesce(l.k, r.k)
Assignments.Builder assignments = Assignments.builder();
ImmutableList.Builder<VariableReferenceExpression> outputs = ImmutableList.builder();
for (Identifier column : joinColumns) {
VariableReferenceExpression output = variableAllocator.newVariable(column, analysis.getType(column));
outputs.add(output);
assignments.put(output, castToRowExpression(new CoalesceExpression(column.getLocation(), createSymbolReference(leftJoinColumns.get(column)), createSymbolReference(rightJoinColumns.get(column)))));
}
for (int field : joinAnalysis.getOtherLeftFields()) {
VariableReferenceExpression variable = left.getFieldMappings().get(field);
outputs.add(variable);
assignments.put(variable, castToRowExpression(createSymbolReference(variable)));
}
for (int field : joinAnalysis.getOtherRightFields()) {
VariableReferenceExpression variable = right.getFieldMappings().get(field);
outputs.add(variable);
assignments.put(variable, castToRowExpression(createSymbolReference(variable)));
}
return new RelationPlan(new ProjectNode(idAllocator.getNextId(), join, assignments.build()), analysis.getScope(node), outputs.build());
}
use of com.facebook.presto.sql.tree.Identifier in project presto by prestodb.
the class QueryRewriter method generateStorageColumnAliases.
private List<Identifier> generateStorageColumnAliases(ResultSetMetaData metadata) {
ImmutableList.Builder<Identifier> aliases = ImmutableList.builder();
Set<String> usedAliases = new HashSet<>();
for (String columnName : getColumnNames(metadata)) {
columnName = sanitizeColumnName(columnName);
String alias = columnName;
int postfix = 1;
while (usedAliases.contains(alias)) {
alias = format("%s__%s", columnName, postfix);
postfix++;
}
aliases.add(new Identifier(alias, true));
usedAliases.add(alias);
}
return aliases.build();
}
use of com.facebook.presto.sql.tree.Identifier in project presto by prestodb.
the class QueryRewriter method rewriteQuery.
public QueryObjectBundle rewriteQuery(@Language("SQL") String query, ClusterType clusterType) {
checkState(prefixes.containsKey(clusterType), "Unsupported cluster type: %s", clusterType);
Statement statement = sqlParser.createStatement(query, PARSING_OPTIONS);
QualifiedName prefix = prefixes.get(clusterType);
List<Property> properties = tableProperties.get(clusterType);
if (statement instanceof CreateTableAsSelect) {
CreateTableAsSelect createTableAsSelect = (CreateTableAsSelect) statement;
QualifiedName temporaryTableName = generateTemporaryName(Optional.of(createTableAsSelect.getName()), prefix);
return new QueryObjectBundle(temporaryTableName, ImmutableList.of(), new CreateTableAsSelect(temporaryTableName, createTableAsSelect.getQuery(), createTableAsSelect.isNotExists(), applyPropertyOverride(createTableAsSelect.getProperties(), properties), createTableAsSelect.isWithData(), createTableAsSelect.getColumnAliases(), createTableAsSelect.getComment()), ImmutableList.of(new DropTable(temporaryTableName, true)), clusterType);
}
if (statement instanceof Insert) {
Insert insert = (Insert) statement;
QualifiedName originalTableName = insert.getTarget();
QualifiedName temporaryTableName = generateTemporaryName(Optional.of(originalTableName), prefix);
return new QueryObjectBundle(temporaryTableName, ImmutableList.of(new CreateTable(temporaryTableName, ImmutableList.of(new LikeClause(originalTableName, Optional.of(INCLUDING))), false, properties, Optional.empty())), new Insert(temporaryTableName, insert.getColumns(), insert.getQuery()), ImmutableList.of(new DropTable(temporaryTableName, true)), clusterType);
}
if (statement instanceof Query) {
QualifiedName temporaryTableName = generateTemporaryName(Optional.empty(), prefix);
ResultSetMetaData metadata = getResultMetadata((Query) statement);
List<Identifier> columnAliases = generateStorageColumnAliases(metadata);
Query rewrite = rewriteNonStorableColumns((Query) statement, metadata);
return new QueryObjectBundle(temporaryTableName, ImmutableList.of(), new CreateTableAsSelect(temporaryTableName, rewrite, false, properties, true, Optional.of(columnAliases), Optional.empty()), ImmutableList.of(new DropTable(temporaryTableName, true)), clusterType);
}
if (statement instanceof CreateView) {
CreateView createView = (CreateView) statement;
QualifiedName temporaryViewName = generateTemporaryName(Optional.empty(), prefix);
ImmutableList.Builder<Statement> setupQueries = ImmutableList.builder();
// Otherwise, do not pre-create temporary view.
try {
String createExistingViewQuery = getOnlyElement(prestoAction.execute(new ShowCreate(VIEW, createView.getName()), REWRITE, SHOW_CREATE_VIEW_CONVERTER).getResults());
CreateView createExistingView = (CreateView) sqlParser.createStatement(createExistingViewQuery, PARSING_OPTIONS);
setupQueries.add(new CreateView(temporaryViewName, createExistingView.getQuery(), false, createExistingView.getSecurity()));
} catch (QueryException e) {
// no-op
}
return new QueryObjectBundle(temporaryViewName, setupQueries.build(), new CreateView(temporaryViewName, createView.getQuery(), createView.isReplace(), createView.getSecurity()), ImmutableList.of(new DropView(temporaryViewName, true)), clusterType);
}
if (statement instanceof CreateTable) {
CreateTable createTable = (CreateTable) statement;
QualifiedName temporaryTableName = generateTemporaryName(Optional.empty(), prefix);
return new QueryObjectBundle(temporaryTableName, ImmutableList.of(), new CreateTable(temporaryTableName, createTable.getElements(), createTable.isNotExists(), applyPropertyOverride(createTable.getProperties(), properties), createTable.getComment()), ImmutableList.of(new DropTable(temporaryTableName, true)), clusterType);
}
throw new IllegalStateException(format("Unsupported query type: %s", statement.getClass()));
}
use of com.facebook.presto.sql.tree.Identifier 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();
}
Aggregations