phoenix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (PHOENIX-514) Support functional indexes
Date Thu, 15 Jan 2015 06:32:35 GMT

    [ https://issues.apache.org/jira/browse/PHOENIX-514?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14278328#comment-14278328
] 

ASF GitHub Bot commented on PHOENIX-514:
----------------------------------------

Github user JamesRTaylor commented on a diff in the pull request:

    https://github.com/apache/phoenix/pull/34#discussion_r22992799
  
    --- Diff: phoenix-core/src/main/java/org/apache/phoenix/compile/IndexColumnExpressionCompiler.java
---
    @@ -0,0 +1,302 @@
    +/*
    + * 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.Collections;
    +import java.util.List;
    +
    +import org.apache.hadoop.hbase.client.Scan;
    +import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
    +import org.apache.phoenix.expression.ColumnExpression;
    +import org.apache.phoenix.expression.Expression;
    +import org.apache.phoenix.jdbc.PhoenixConnection;
    +import org.apache.phoenix.parse.AddParseNode;
    +import org.apache.phoenix.parse.AndParseNode;
    +import org.apache.phoenix.parse.ArrayAllComparisonNode;
    +import org.apache.phoenix.parse.ArrayAnyComparisonNode;
    +import org.apache.phoenix.parse.ArrayElemRefNode;
    +import org.apache.phoenix.parse.CaseParseNode;
    +import org.apache.phoenix.parse.CastParseNode;
    +import org.apache.phoenix.parse.ColumnDef;
    +import org.apache.phoenix.parse.ColumnParseNode;
    +import org.apache.phoenix.parse.ComparisonParseNode;
    +import org.apache.phoenix.parse.DivideParseNode;
    +import org.apache.phoenix.parse.FunctionParseNode;
    +import org.apache.phoenix.parse.ModulusParseNode;
    +import org.apache.phoenix.parse.MultiplyParseNode;
    +import org.apache.phoenix.parse.NamedTableNode;
    +import org.apache.phoenix.parse.NotParseNode;
    +import org.apache.phoenix.parse.OrParseNode;
    +import org.apache.phoenix.parse.ParseNode;
    +import org.apache.phoenix.parse.RowValueConstructorParseNode;
    +import org.apache.phoenix.parse.SQLParser;
    +import org.apache.phoenix.parse.StringConcatParseNode;
    +import org.apache.phoenix.parse.SubtractParseNode;
    +import org.apache.phoenix.parse.TableName;
    +import org.apache.phoenix.schema.PColumn;
    +import org.apache.phoenix.schema.PTable;
    +import org.apache.phoenix.schema.PTableType;
    +import org.apache.phoenix.util.IndexUtil;
    +
    +/**
    + * Visitor that checks if nodes other than ColumnParseNode are present as 
    + * an expression in an index. If the expression is present, then the node is
    + * not visited but processed as a ColumnParseNode.
    + */
    +public class IndexColumnExpressionCompiler extends ExpressionCompiler {
    +	
    +	IndexColumnExpressionCompiler(StatementContext context) {
    +        super(context);
    +    }
    +
    +	IndexColumnExpressionCompiler(StatementContext context, boolean resolveViewConstants)
{
    +        super(context, resolveViewConstants);
    +    }
    +
    +	IndexColumnExpressionCompiler(StatementContext context, GroupBy groupBy) {
    +		super(context, groupBy);
    +    }
    +
    +	IndexColumnExpressionCompiler(StatementContext context, GroupBy groupBy, boolean resolveViewConstants)
{
    +		super(context, groupBy, resolveViewConstants);
    +    }
    +	
    +    /**
    +     * Returns the compiled expression
    +     * 
    +     * @param node
    +     *            data table parse node
    +     */
    +	private Expression getExpression(ParseNode node) throws SQLException {
    +		PhoenixConnection connection = this.context.getConnection();
    +        PTable indexTable = this.context.getCurrentTable().getTable();
    +        NamedTableNode dataTableNode = NamedTableNode.create(null, TableName.create(indexTable.getParentSchemaName().getString(),

    +        		indexTable.getParentTableName().getString()), Collections.<ColumnDef>emptyList());
    +        ColumnResolver resolver = FromCompiler.getResolver(dataTableNode, connection);
    +		StatementContext context = new StatementContext(this.context.getStatement(), resolver,
new Scan(), new SequenceManager(this.context.getStatement()));        
    +        ExpressionCompiler expressionCompiler = new ExpressionCompiler(context);
    +        return node.accept(expressionCompiler);		
    +	}
    +
    +	/**
    +	 * @return true if current table is an index and there is an expression that matches
the given node
    +	 */
    +	private boolean matchesIndexedExpression(ParseNode node) throws SQLException {   
    +		if (context.getCurrentTable().getTable().getType()!=PTableType.INDEX) {
    +			return false;
    +		}
    +		DataTableNodeRewriter statementRewriter = new DataTableNodeRewriter();
    +        ParseNode dataTableParseNode = node.accept(statementRewriter);
    +		Expression dataTableExpression = getExpression(dataTableParseNode);
    +		// if the node matches a column expression
    +		if (ColumnExpression.class.isAssignableFrom(dataTableExpression.getClass())) {
    +			return false;
    +		}
    +	    for ( PColumn column : this.context.getCurrentTable().getTable().getColumns()) {
    +	        if (column.getExpressionStr()!=null) {
    +	            ParseNode parseNode = SQLParser.parseCondition(column.getExpressionStr());
    +	            Expression expression = getExpression(parseNode);
    +	            if (expression.equals(dataTableExpression))
    +	                return true;
    +	        }
    +	    }
    +		return false;
    +    }
    +    
    +    private Expression convertAndVisitParseNode(ParseNode node) throws SQLException {
    +        DataTableNodeRewriter statementRewriter = new DataTableNodeRewriter();
    +        ParseNode dataTableParseNode = node.accept(statementRewriter);
    +    	Expression expression = getExpression(dataTableParseNode);
    +    	ColumnParseNode columnParseNode = new ColumnParseNode(null, IndexUtil.getIndexColumnName(null,String.valueOf(expression.hashCode())),
null);
    +    	return visit(columnParseNode);
    +    }
    +
    +	@Override
    +    public boolean visitEnter(ComparisonParseNode node) throws SQLException {
    +		// do not visit this node if it matches an expression that is indexed,  it will be
converted to a ColumnParseNode and processed in visitLeave
    +		return matchesIndexedExpression(node) ? false : super.visitEnter(node);
    +    }
    +
    +    @Override
    +    public Expression visitLeave(ComparisonParseNode node, List<Expression> children)
throws SQLException {
    --- End diff --
    
    Having to specialize every visitorLeave is a bit painful. One possibility would be to
make the wrapGroupByExpression method protected, override it, and do a super.wrapGroupByExpression()
call (and perhaps rename it). I believe that method is called from every visitorLeave method.


> Support functional indexes
> --------------------------
>
>                 Key: PHOENIX-514
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-514
>             Project: Phoenix
>          Issue Type: Task
>            Reporter: James Taylor
>            Assignee: Thomas D'Silva
>              Labels: enhancement
>
> Instead of only defining the set of columns from the data table that make up an index,
you should be able to use expressions.  For example:
>       CREATE INDEX upper_last_name_idx ON person (UPPER(last_name))
> Then in queries that use UPPER(last_name), we can replace them with column references
to the index table.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message