Search in sources :

Example 26 with ColumnNotFoundException

use of org.apache.phoenix.schema.ColumnNotFoundException in project phoenix by apache.

the class ExpressionCompiler method resolveColumn.

/**
 * Called by visitor to resolve a column expression node into a column reference.
 * Derived classes may use this as a hook to trap all column resolves.
 * @param node a column expression node
 * @return a resolved ColumnRef
 * @throws SQLException if the column expression node does not refer to a known/unambiguous column
 */
protected ColumnRef resolveColumn(ColumnParseNode node) throws SQLException {
    ColumnRef ref = null;
    try {
        ref = context.getResolver().resolveColumn(node.getSchemaName(), node.getTableName(), node.getName());
    } catch (ColumnNotFoundException e) {
        // operation given that we know the join is local.
        if (context.getCurrentTable().getTable().getIndexType() == IndexType.LOCAL) {
            try {
                return new LocalIndexDataColumnRef(context, node.getName());
            } catch (ColumnFamilyNotFoundException c) {
                throw e;
            }
        } else {
            throw e;
        }
    }
    PTable table = ref.getTable();
    int pkPosition = ref.getPKSlotPosition();
    // Disallow explicit reference to salting column, tenant ID column, and index ID column
    if (pkPosition >= 0) {
        boolean isSalted = table.getBucketNum() != null;
        boolean isMultiTenant = context.getConnection().getTenantId() != null && table.isMultiTenant();
        boolean isSharedViewIndex = table.getViewIndexId() != null;
        int minPosition = (isSalted ? 1 : 0) + (isMultiTenant ? 1 : 0) + (isSharedViewIndex ? 1 : 0);
        if (pkPosition < minPosition) {
            throw new ColumnNotFoundException(table.getSchemaName().getString(), table.getTableName().getString(), null, ref.getColumn().getName().getString());
        }
    }
    return ref;
}
Also used : ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) ColumnRef(org.apache.phoenix.schema.ColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) LocalIndexDataColumnRef(org.apache.phoenix.schema.LocalIndexDataColumnRef) ColumnFamilyNotFoundException(org.apache.phoenix.schema.ColumnFamilyNotFoundException) PTable(org.apache.phoenix.schema.PTable)

Example 27 with ColumnNotFoundException

use of org.apache.phoenix.schema.ColumnNotFoundException in project phoenix by apache.

the class QueryOptimizer method addPlan.

private QueryPlan addPlan(PhoenixStatement statement, SelectStatement select, PTable index, List<? extends PDatum> targetColumns, ParallelIteratorFactory parallelIteratorFactory, QueryPlan dataPlan, boolean isHinted) throws SQLException {
    int nColumns = dataPlan.getProjector().getColumnCount();
    String tableAlias = dataPlan.getTableRef().getTableAlias();
    // double quote in case it's case sensitive
    String alias = tableAlias == null ? null : '"' + tableAlias + '"';
    String schemaName = index.getParentSchemaName().getString();
    schemaName = schemaName.length() == 0 ? null : '"' + schemaName + '"';
    String tableName = '"' + index.getTableName().getString() + '"';
    TableNode table = FACTORY.namedTable(alias, FACTORY.table(schemaName, tableName), select.getTableSamplingRate());
    SelectStatement indexSelect = FACTORY.select(select, table);
    ColumnResolver resolver = FromCompiler.getResolverForQuery(indexSelect, statement.getConnection());
    // We will or will not do tuple projection according to the data plan.
    boolean isProjected = dataPlan.getContext().getResolver().getTables().get(0).getTable().getType() == PTableType.PROJECTED;
    // Check index state of now potentially updated index table to make sure it's active
    TableRef indexTableRef = resolver.getTables().get(0);
    PTable indexTable = indexTableRef.getTable();
    PIndexState indexState = indexTable.getIndexState();
    Map<TableRef, QueryPlan> dataPlans = Collections.singletonMap(indexTableRef, dataPlan);
    if (indexState == PIndexState.ACTIVE || indexState == PIndexState.PENDING_ACTIVE || (indexState == PIndexState.PENDING_DISABLE && isUnderPendingDisableThreshold(indexTableRef.getCurrentTime(), indexTable.getIndexDisableTimestamp()))) {
        try {
            // translate nodes that match expressions that are indexed to the associated column parse node
            indexSelect = ParseNodeRewriter.rewrite(indexSelect, new IndexExpressionParseNodeRewriter(index, null, statement.getConnection(), indexSelect.getUdfParseNodes()));
            QueryCompiler compiler = new QueryCompiler(statement, indexSelect, resolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager(), isProjected, true, dataPlans);
            QueryPlan plan = compiler.compile();
            // then we can use the index even the query doesn't have where clause.
            if (index.getIndexType() == IndexType.LOCAL && indexSelect.getWhere() == null && !plan.getContext().getDataColumns().isEmpty()) {
                return null;
            }
            indexTableRef = plan.getTableRef();
            indexTable = indexTableRef.getTable();
            indexState = indexTable.getIndexState();
            // must contain all columns from the data table to be able to be used.
            if (indexState == PIndexState.ACTIVE || indexState == PIndexState.PENDING_ACTIVE || (indexState == PIndexState.PENDING_DISABLE && isUnderPendingDisableThreshold(indexTableRef.getCurrentTime(), indexTable.getIndexDisableTimestamp()))) {
                if (plan.getProjector().getColumnCount() == nColumns) {
                    return plan;
                } else if (index.getIndexType() == IndexType.GLOBAL) {
                    String schemaNameStr = index.getSchemaName() == null ? null : index.getSchemaName().getString();
                    String tableNameStr = index.getTableName() == null ? null : index.getTableName().getString();
                    throw new ColumnNotFoundException(schemaNameStr, tableNameStr, null, "*");
                }
            }
        } catch (ColumnNotFoundException e) {
            /* Means that a column is being used that's not in our index.
                 * Since we currently don't keep stats, we don't know the selectivity of the index.
                 * For now, if this is a hinted plan, we will try rewriting the query as a subquery;
                 * otherwise we just don't use this index (as opposed to trying to join back from
                 * the index table to the data table.
                 */
            SelectStatement dataSelect = (SelectStatement) dataPlan.getStatement();
            ParseNode where = dataSelect.getWhere();
            if (isHinted && where != null) {
                StatementContext context = new StatementContext(statement, resolver);
                WhereConditionRewriter whereRewriter = new WhereConditionRewriter(FromCompiler.getResolver(dataPlan.getTableRef()), context);
                where = where.accept(whereRewriter);
                if (where != null) {
                    PTable dataTable = dataPlan.getTableRef().getTable();
                    List<PColumn> pkColumns = dataTable.getPKColumns();
                    List<AliasedNode> aliasedNodes = Lists.<AliasedNode>newArrayListWithExpectedSize(pkColumns.size());
                    List<ParseNode> nodes = Lists.<ParseNode>newArrayListWithExpectedSize(pkColumns.size());
                    boolean isSalted = dataTable.getBucketNum() != null;
                    boolean isTenantSpecific = dataTable.isMultiTenant() && statement.getConnection().getTenantId() != null;
                    int posOffset = (isSalted ? 1 : 0) + (isTenantSpecific ? 1 : 0);
                    for (int i = posOffset; i < pkColumns.size(); i++) {
                        PColumn column = pkColumns.get(i);
                        String indexColName = IndexUtil.getIndexColumnName(column);
                        ParseNode indexColNode = new ColumnParseNode(null, '"' + indexColName + '"', indexColName);
                        PDataType indexColType = IndexUtil.getIndexColumnDataType(column);
                        PDataType dataColType = column.getDataType();
                        if (indexColType != dataColType) {
                            indexColNode = FACTORY.cast(indexColNode, dataColType, null, null);
                        }
                        aliasedNodes.add(FACTORY.aliasedNode(null, indexColNode));
                        nodes.add(new ColumnParseNode(null, '"' + column.getName().getString() + '"'));
                    }
                    SelectStatement innerSelect = FACTORY.select(indexSelect.getFrom(), indexSelect.getHint(), false, aliasedNodes, where, null, null, null, null, null, indexSelect.getBindCount(), false, indexSelect.hasSequence(), Collections.<SelectStatement>emptyList(), indexSelect.getUdfParseNodes());
                    ParseNode outerWhere = FACTORY.in(nodes.size() == 1 ? nodes.get(0) : FACTORY.rowValueConstructor(nodes), FACTORY.subquery(innerSelect, false), false, true);
                    ParseNode extractedCondition = whereRewriter.getExtractedCondition();
                    if (extractedCondition != null) {
                        outerWhere = FACTORY.and(Lists.newArrayList(outerWhere, extractedCondition));
                    }
                    HintNode hint = HintNode.combine(HintNode.subtract(indexSelect.getHint(), new Hint[] { Hint.INDEX, Hint.NO_CHILD_PARENT_JOIN_OPTIMIZATION }), FACTORY.hint("NO_INDEX"));
                    SelectStatement query = FACTORY.select(dataSelect, hint, outerWhere);
                    ColumnResolver queryResolver = FromCompiler.getResolverForQuery(query, statement.getConnection());
                    query = SubqueryRewriter.transform(query, queryResolver, statement.getConnection());
                    queryResolver = FromCompiler.getResolverForQuery(query, statement.getConnection());
                    query = StatementNormalizer.normalize(query, queryResolver);
                    QueryPlan plan = new QueryCompiler(statement, query, queryResolver, targetColumns, parallelIteratorFactory, dataPlan.getContext().getSequenceManager(), isProjected, true, dataPlans).compile();
                    return plan;
                }
            }
        }
    }
    return null;
}
Also used : PIndexState(org.apache.phoenix.schema.PIndexState) BaseQueryPlan(org.apache.phoenix.execute.BaseQueryPlan) QueryPlan(org.apache.phoenix.compile.QueryPlan) QueryCompiler(org.apache.phoenix.compile.QueryCompiler) Hint(org.apache.phoenix.parse.HintNode.Hint) PTable(org.apache.phoenix.schema.PTable) StatementContext(org.apache.phoenix.compile.StatementContext) PColumn(org.apache.phoenix.schema.PColumn) SelectStatement(org.apache.phoenix.parse.SelectStatement) ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) PDataType(org.apache.phoenix.schema.types.PDataType) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) HintNode(org.apache.phoenix.parse.HintNode) TableNode(org.apache.phoenix.parse.TableNode) JoinTableNode(org.apache.phoenix.parse.JoinTableNode) NamedTableNode(org.apache.phoenix.parse.NamedTableNode) BindTableNode(org.apache.phoenix.parse.BindTableNode) DerivedTableNode(org.apache.phoenix.parse.DerivedTableNode) ColumnParseNode(org.apache.phoenix.parse.ColumnParseNode) AndParseNode(org.apache.phoenix.parse.AndParseNode) ParseNode(org.apache.phoenix.parse.ParseNode) List(java.util.List) IndexExpressionParseNodeRewriter(org.apache.phoenix.parse.IndexExpressionParseNodeRewriter) ColumnResolver(org.apache.phoenix.compile.ColumnResolver) TableRef(org.apache.phoenix.schema.TableRef)

Example 28 with ColumnNotFoundException

use of org.apache.phoenix.schema.ColumnNotFoundException in project phoenix by apache.

the class PhoenixRuntime method generateColumnInfo.

/**
 * Get list of ColumnInfos that contain Column Name and its associated
 * PDataType for an import. The supplied list of columns can be null -- if it is non-null,
 * it represents a user-supplied list of columns to be imported.
 *
 * @param conn Phoenix connection from which metadata will be read
 * @param tableName Phoenix table name whose columns are to be checked. Can include a schema
 *                  name
 * @param columns user-supplied list of import columns, can be null
 */
public static List<ColumnInfo> generateColumnInfo(Connection conn, String tableName, List<String> columns) throws SQLException {
    PTable table = PhoenixRuntime.getTable(conn, SchemaUtil.normalizeFullTableName(tableName));
    List<ColumnInfo> columnInfoList = Lists.newArrayList();
    Set<String> unresolvedColumnNames = new TreeSet<String>();
    if (columns == null || columns.isEmpty()) {
        // use all columns in the table
        int offset = (table.getBucketNum() == null ? 0 : 1);
        for (int i = offset; i < table.getColumns().size(); i++) {
            PColumn pColumn = table.getColumns().get(i);
            columnInfoList.add(PhoenixRuntime.getColumnInfo(pColumn));
        }
    } else {
        // Leave "null" as indication to skip b/c it doesn't exist
        for (int i = 0; i < columns.size(); i++) {
            String columnName = columns.get(i);
            try {
                ColumnInfo columnInfo = PhoenixRuntime.getColumnInfo(table, columnName);
                columnInfoList.add(columnInfo);
            } catch (ColumnNotFoundException cnfe) {
                unresolvedColumnNames.add(columnName);
            } catch (AmbiguousColumnException ace) {
                unresolvedColumnNames.add(columnName);
            }
        }
    }
    // if there exists columns that cannot be resolved, error out.
    if (unresolvedColumnNames.size() > 0) {
        StringBuilder exceptionMessage = new StringBuilder();
        boolean first = true;
        exceptionMessage.append("Unable to resolve these column names:\n");
        for (String col : unresolvedColumnNames) {
            if (first)
                first = false;
            else
                exceptionMessage.append(",");
            exceptionMessage.append(col);
        }
        exceptionMessage.append("\nAvailable columns with column families:\n");
        first = true;
        for (PColumn pColumn : table.getColumns()) {
            if (first)
                first = false;
            else
                exceptionMessage.append(",");
            exceptionMessage.append(pColumn.toString());
        }
        throw new SQLException(exceptionMessage.toString());
    }
    return columnInfoList;
}
Also used : SQLException(java.sql.SQLException) PTable(org.apache.phoenix.schema.PTable) PColumn(org.apache.phoenix.schema.PColumn) ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) TreeSet(java.util.TreeSet) AmbiguousColumnException(org.apache.phoenix.schema.AmbiguousColumnException)

Example 29 with ColumnNotFoundException

use of org.apache.phoenix.schema.ColumnNotFoundException in project phoenix by apache.

the class IndexUtil method getDataColumnOrNull.

public static PColumn getDataColumnOrNull(PTable dataTable, String indexColumnName) {
    int pos = indexColumnName.indexOf(INDEX_COLUMN_NAME_SEP);
    if (pos < 0) {
        return null;
    }
    if (pos == 0) {
        try {
            return dataTable.getPKColumn(indexColumnName.substring(1));
        } catch (ColumnNotFoundException e) {
            return null;
        }
    }
    PColumnFamily family;
    try {
        family = dataTable.getColumnFamily(getDataColumnFamilyName(indexColumnName));
    } catch (ColumnFamilyNotFoundException e) {
        return null;
    }
    try {
        return family.getPColumnForColumnName(indexColumnName.substring(pos + 1));
    } catch (ColumnNotFoundException e) {
        return null;
    }
}
Also used : ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) PColumnFamily(org.apache.phoenix.schema.PColumnFamily) ColumnFamilyNotFoundException(org.apache.phoenix.schema.ColumnFamilyNotFoundException)

Example 30 with ColumnNotFoundException

use of org.apache.phoenix.schema.ColumnNotFoundException in project DataX by alibaba.

the class HbaseSQLHelper method validateConfig.

/**
 * 校验配置
 */
public static void validateConfig(HbaseSQLWriterConfig cfg) {
    // 校验集群地址:尝试连接,连不上就说明有问题,抛错退出
    Connection conn = getJdbcConnection(cfg);
    // 检查表:存在,可用
    checkTable(conn, cfg.getNamespace(), cfg.getTableName(), cfg.isThinClient());
    // 校验元数据:配置中给出的列必须是目的表中已经存在的列
    PTable schema = null;
    try {
        schema = getTableSchema(conn, cfg.getNamespace(), cfg.getTableName(), cfg.isThinClient());
    } catch (SQLException e) {
        throw DataXException.asDataXException(HbaseSQLWriterErrorCode.GET_HBASE_CONNECTION_ERROR, "无法获取目的表" + cfg.getTableName() + "的元数据信息,表可能不是SQL表或表名配置错误,请检查您的配置 或者 联系 HBase 管理员.", e);
    }
    try {
        List<String> columnNames = cfg.getColumns();
        for (String colName : columnNames) {
            schema.getColumnForColumnName(colName);
        }
    } catch (ColumnNotFoundException e) {
        // 用户配置的列名在元数据中不存在
        throw DataXException.asDataXException(HbaseSQLWriterErrorCode.ILLEGAL_VALUE, "您配置的列" + e.getColumnName() + "在目的表" + cfg.getTableName() + "的元数据中不存在,请检查您的配置 或者 联系 HBase 管理员.", e);
    } catch (SQLException e) {
        // 列名有二义性或者其他问题
        throw DataXException.asDataXException(HbaseSQLWriterErrorCode.ILLEGAL_VALUE, "目的表" + cfg.getTableName() + "的列信息校验失败,请检查您的配置 或者 联系 HBase 管理员.", e);
    }
}
Also used : ColumnNotFoundException(org.apache.phoenix.schema.ColumnNotFoundException) SQLException(java.sql.SQLException) Connection(java.sql.Connection) PhoenixConnection(org.apache.phoenix.jdbc.PhoenixConnection) PTable(org.apache.phoenix.schema.PTable)

Aggregations

ColumnNotFoundException (org.apache.phoenix.schema.ColumnNotFoundException)30 PhoenixConnection (org.apache.phoenix.jdbc.PhoenixConnection)16 PTable (org.apache.phoenix.schema.PTable)14 Connection (java.sql.Connection)13 PColumn (org.apache.phoenix.schema.PColumn)13 ColumnFamilyNotFoundException (org.apache.phoenix.schema.ColumnFamilyNotFoundException)12 Test (org.junit.Test)11 ColumnRef (org.apache.phoenix.schema.ColumnRef)7 PColumnFamily (org.apache.phoenix.schema.PColumnFamily)7 ByteString (com.google.protobuf.ByteString)6 SQLException (java.sql.SQLException)6 ArrayList (java.util.ArrayList)6 Properties (java.util.Properties)6 Mutation (org.apache.hadoop.hbase.client.Mutation)6 RowLock (org.apache.hadoop.hbase.regionserver.Region.RowLock)6 ResultSet (java.sql.ResultSet)5 List (java.util.List)5 Delete (org.apache.hadoop.hbase.client.Delete)4 Expression (org.apache.phoenix.expression.Expression)4 KeyValueColumnExpression (org.apache.phoenix.expression.KeyValueColumnExpression)4