Search in sources :

Example 41 with Identifier

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")))));
}
Also used : Identifier(com.facebook.presto.sql.tree.Identifier) QueryUtil.quotedIdentifier(com.facebook.presto.sql.QueryUtil.quotedIdentifier) LambdaArgumentDeclaration(com.facebook.presto.sql.tree.LambdaArgumentDeclaration) FunctionCall(com.facebook.presto.sql.tree.FunctionCall) LambdaExpression(com.facebook.presto.sql.tree.LambdaExpression) Test(org.testng.annotations.Test)

Example 42 with Identifier

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());
}
Also used : Cast(com.facebook.presto.sql.tree.Cast) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) LateralJoinNode(com.facebook.presto.sql.planner.plan.LateralJoinNode) JoinNode(com.facebook.presto.sql.planner.plan.JoinNode) Assignments(com.facebook.presto.spi.plan.Assignments) JoinUsing(com.facebook.presto.sql.tree.JoinUsing) TypeUtils.isEnumType(com.facebook.presto.common.type.TypeUtils.isEnumType) ArrayType(com.facebook.presto.common.type.ArrayType) RowType(com.facebook.presto.common.type.RowType) MapType(com.facebook.presto.common.type.MapType) Type(com.facebook.presto.common.type.Type) RelationType(com.facebook.presto.sql.analyzer.RelationType) Identifier(com.facebook.presto.sql.tree.Identifier) Analysis(com.facebook.presto.sql.analyzer.Analysis) VariableReferenceExpression(com.facebook.presto.spi.relation.VariableReferenceExpression) ProjectNode(com.facebook.presto.spi.plan.ProjectNode) CoalesceExpression(com.facebook.presto.sql.tree.CoalesceExpression)

Example 43 with Identifier

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();
}
Also used : Identifier(com.facebook.presto.sql.tree.Identifier) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) HashSet(java.util.HashSet)

Example 44 with Identifier

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()));
}
Also used : LikeClause(com.facebook.presto.sql.tree.LikeClause) Query(com.facebook.presto.sql.tree.Query) Statement(com.facebook.presto.sql.tree.Statement) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) QualifiedName(com.facebook.presto.sql.tree.QualifiedName) DropView(com.facebook.presto.sql.tree.DropView) CreateTable(com.facebook.presto.sql.tree.CreateTable) DropTable(com.facebook.presto.sql.tree.DropTable) Insert(com.facebook.presto.sql.tree.Insert) CreateView(com.facebook.presto.sql.tree.CreateView) ResultSetMetaData(java.sql.ResultSetMetaData) QueryException(com.facebook.presto.verifier.framework.QueryException) Identifier(com.facebook.presto.sql.tree.Identifier) ShowCreate(com.facebook.presto.sql.tree.ShowCreate) CreateTableAsSelect(com.facebook.presto.sql.tree.CreateTableAsSelect) QueryObjectBundle(com.facebook.presto.verifier.framework.QueryObjectBundle) Property(com.facebook.presto.sql.tree.Property)

Example 45 with Identifier

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();
}
Also used : Identifier(com.facebook.presto.sql.tree.Identifier) VerifierUtil.delimitedIdentifier(com.facebook.presto.verifier.framework.VerifierUtil.delimitedIdentifier) Optional(java.util.Optional) Expression(com.facebook.presto.sql.tree.Expression) LongLiteral(com.facebook.presto.sql.tree.LongLiteral) ImmutableList(com.google.common.collect.ImmutableList) SingleColumn(com.facebook.presto.sql.tree.SingleColumn)

Aggregations

Identifier (com.facebook.presto.sql.tree.Identifier)46 Test (org.testng.annotations.Test)31 QueryUtil.quotedIdentifier (com.facebook.presto.sql.QueryUtil.quotedIdentifier)27 LongLiteral (com.facebook.presto.sql.tree.LongLiteral)15 Query (com.facebook.presto.sql.tree.Query)11 FunctionCall (com.facebook.presto.sql.tree.FunctionCall)10 AllColumns (com.facebook.presto.sql.tree.AllColumns)9 DropTable (com.facebook.presto.sql.tree.DropTable)9 QualifiedName (com.facebook.presto.sql.tree.QualifiedName)9 QuerySpecification (com.facebook.presto.sql.tree.QuerySpecification)9 Table (com.facebook.presto.sql.tree.Table)9 ComparisonExpression (com.facebook.presto.sql.tree.ComparisonExpression)8 CreateTable (com.facebook.presto.sql.tree.CreateTable)8 Expression (com.facebook.presto.sql.tree.Expression)8 QueryUtil.simpleQuery (com.facebook.presto.sql.QueryUtil.simpleQuery)7 SingleColumn (com.facebook.presto.sql.tree.SingleColumn)7 StringLiteral (com.facebook.presto.sql.tree.StringLiteral)7 WithQuery (com.facebook.presto.sql.tree.WithQuery)7 CreateTableAsSelect (com.facebook.presto.sql.tree.CreateTableAsSelect)6 DereferenceExpression (com.facebook.presto.sql.tree.DereferenceExpression)6