All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.phoenix.compile.PostIndexDDLCompiler Maven / Gradle / Ivy

There is a newer version: 4.15.0-HBase-1.5
Show newest version
/*
 * 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.compile;

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

import org.apache.phoenix.execute.MutationState;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.schema.PColumn;
import org.apache.phoenix.schema.PColumnFamily;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.TableRef;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.StringUtil;

import com.google.common.collect.Lists;


/**
 * Class that compiles plan to generate initial data values after a DDL command for
 * index table.
 */
public class PostIndexDDLCompiler {
    private final PhoenixConnection connection;
    private final TableRef dataTableRef;
    private List indexColumnNames;
    private List dataColumnNames;
    private String selectQuery;
    
    public PostIndexDDLCompiler(PhoenixConnection connection, TableRef dataTableRef) {
        this.connection = connection;
        this.dataTableRef = dataTableRef;
        indexColumnNames = Lists.newArrayList();
        dataColumnNames = Lists.newArrayList();
    }

    public MutationPlan compile(final PTable indexTable) throws SQLException {
        /*
         * Compiles an UPSERT SELECT command to read from the data table and populate the index table
         */
        StringBuilder indexColumns = new StringBuilder();
        StringBuilder dataColumns = new StringBuilder();
        
        // Add the pk index columns
        List indexPKColumns = indexTable.getPKColumns();
        int nIndexPKColumns = indexTable.getPKColumns().size();
        boolean isSalted = indexTable.getBucketNum() != null;
        boolean isMultiTenant = connection.getTenantId() != null && indexTable.isMultiTenant();
        boolean isViewIndex = indexTable.getViewIndexId()!=null;
        int posOffset = (isSalted ? 1 : 0) + (isMultiTenant ? 1 : 0) + (isViewIndex ? 1 : 0);
        for (int i = posOffset; i < nIndexPKColumns; i++) {
            PColumn col = indexPKColumns.get(i);
            String indexColName = col.getName().getString();
            // need to escape backslash as this used in the SELECT statement
            String dataColName = StringUtil.escapeBackslash(col.getExpressionStr());
            dataColumns.append(dataColName).append(",");
            indexColumns.append('"').append(indexColName).append("\",");
            indexColumnNames.add(indexColName);
            dataColumnNames.add(dataColName);
        }
        
        // Add the covered columns
        for (PColumnFamily family : indexTable.getColumnFamilies()) {
            for (PColumn col : family.getColumns()) {
                if (col.getViewConstant() == null) {
                    String indexColName = col.getName().getString();
                    String dataFamilyName = IndexUtil.getDataColumnFamilyName(indexColName);
                    String dataColumnName = IndexUtil.getDataColumnName(indexColName);
                    if (!dataFamilyName.equals("")) {
                        dataColumns.append('"').append(dataFamilyName).append("\".");
                    }
                    dataColumns.append('"').append(dataColumnName).append("\",");
                    indexColumns.append('"').append(indexColName).append("\",");
                    indexColumnNames.add(indexColName);
                    dataColumnNames.add(dataColumnName);
                }
            }
        }

        final PTable dataTable = dataTableRef.getTable();
        dataColumns.setLength(dataColumns.length()-1);
        indexColumns.setLength(indexColumns.length()-1);
        String schemaName = dataTable.getSchemaName().getString();
        String tableName = indexTable.getTableName().getString();
        
        StringBuilder updateStmtStr = new StringBuilder();
        updateStmtStr.append("UPSERT /*+ NO_INDEX */ INTO ").append(schemaName.length() == 0 ? "" : '"' + schemaName + "\".").append('"').append(tableName).append("\"(")
           .append(indexColumns).append(") ");
        final StringBuilder selectQueryBuilder = new StringBuilder();
        selectQueryBuilder.append(" SELECT /*+ NO_INDEX */ ").append(dataColumns).append(" FROM ")
        .append(schemaName.length() == 0 ? "" : '"' + schemaName + "\".").append('"').append(dataTable.getTableName().getString()).append('"');
        this.selectQuery = selectQueryBuilder.toString();
        updateStmtStr.append(this.selectQuery);
        
        try (final PhoenixStatement statement = new PhoenixStatement(connection)) {
            DelegateMutationPlan delegate = new DelegateMutationPlan(statement.compileMutation(updateStmtStr.toString())) {
                @Override
                public MutationState execute() throws SQLException {
                    connection.getMutationState().commitDDLFence(dataTable);
                    return super.execute();
                }
            };
            return delegate;
        }
    }

    public List getIndexColumnNames() {
        return indexColumnNames;
    }

    public List getDataColumnNames() {
        return dataColumnNames;
    }

    public String getSelectQuery() {
        return selectQuery;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy