org.apache.phoenix.parse.IndexExpressionParseNodeRewriter.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.phoenix.parse.IndexExpressionParseNodeRewriter.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
 * file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by
 * applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.apache.phoenix.parse;

import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.phoenix.compile.ColumnResolver;
import org.apache.phoenix.compile.ExpressionCompiler;
import org.apache.phoenix.compile.FromCompiler;
import org.apache.phoenix.compile.IndexStatementRewriter;
import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.types.PDataType;
import org.apache.phoenix.util.IndexUtil;

import com.google.common.collect.Maps;

/**
 * Used to replace parse nodes in a SelectStatement that match expressions that are present in an indexed with the
 * corresponding {@link ColumnParseNode}
 */
public class IndexExpressionParseNodeRewriter extends ParseNodeRewriter {

    private final Map<ParseNode, ParseNode> indexedParseNodeToColumnParseNodeMap;

    public IndexExpressionParseNodeRewriter(PTable index, PhoenixConnection connection,
            Map<String, UDFParseNode> udfParseNodes) throws SQLException {
        indexedParseNodeToColumnParseNodeMap = Maps.newHashMapWithExpectedSize(index.getColumns().size());
        NamedTableNode tableNode = NamedTableNode.create(null,
                TableName.create(index.getParentSchemaName().getString(), index.getParentTableName().getString()),
                Collections.<ColumnDef>emptyList());
        ColumnResolver dataResolver = FromCompiler.getResolver(tableNode, connection, udfParseNodes);
        StatementContext context = new StatementContext(new PhoenixStatement(connection), dataResolver);
        IndexStatementRewriter rewriter = new IndexStatementRewriter(dataResolver, null);
        ExpressionCompiler expressionCompiler = new ExpressionCompiler(context);
        int indexPosOffset = (index.getBucketNum() == null ? 0 : 1) + (index.isMultiTenant() ? 1 : 0)
                + (index.getViewIndexId() == null ? 0 : 1);
        List<PColumn> pkColumns = index.getPKColumns();
        for (int i = indexPosOffset; i < pkColumns.size(); ++i) {
            PColumn column = pkColumns.get(i);
            String expressionStr = IndexUtil.getIndexColumnExpressionStr(column);
            ParseNode expressionParseNode = SQLParser.parseCondition(expressionStr);
            String colName = "\"" + column.getName().getString() + "\"";
            Expression dataExpression = expressionParseNode.accept(expressionCompiler);
            PDataType expressionDataType = dataExpression.getDataType();
            ParseNode indexedParseNode = expressionParseNode.accept(rewriter);
            PDataType indexColType = IndexUtil.getIndexColumnDataType(dataExpression.isNullable(),
                    expressionDataType);
            ParseNode columnParseNode = new ColumnParseNode(null, colName, null);
            if (indexColType != expressionDataType) {
                columnParseNode = NODE_FACTORY.cast(columnParseNode, expressionDataType, null, null);
            }
            indexedParseNodeToColumnParseNodeMap.put(indexedParseNode, columnParseNode);
        }
    }

    @Override
    protected ParseNode leaveCompoundNode(CompoundParseNode node, List<ParseNode> children,
            CompoundNodeFactory factory) {
        return indexedParseNodeToColumnParseNodeMap.containsKey(node)
                ? indexedParseNodeToColumnParseNodeMap.get(node)
                : super.leaveCompoundNode(node, children, factory);
    }

}