Package com.alibaba.druid.hdriver.impl.execute

Source Code of com.alibaba.druid.hdriver.impl.execute.SingleTableQueryExecutePlan

package com.alibaba.druid.hdriver.impl.execute;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterList;
import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;

import com.alibaba.druid.hdriver.impl.HBaseConnectionImpl;
import com.alibaba.druid.hdriver.impl.HPreparedStatementImpl;
import com.alibaba.druid.hdriver.impl.HResultSetMetaDataImpl;
import com.alibaba.druid.hdriver.impl.HScannerResultSetImpl;
import com.alibaba.druid.hdriver.impl.mapping.HMapping;
import com.alibaba.druid.hdriver.impl.mapping.HMappingDefaultImpl;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOpExpr;
import com.alibaba.druid.sql.ast.expr.SQLBinaryOperator;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.visitor.SQLEvalVisitorUtils;

public class SingleTableQueryExecutePlan extends SingleTableExecutePlan {

    private List<String>           columeNames = new ArrayList<String>();
    private List<SQLExpr>          conditions  = new ArrayList<SQLExpr>();

    private HResultSetMetaDataImpl resultMetaData;

    private String                 dbType      = "hbase";

    private Scan                   scan;
    private HPreparedStatementImpl statement;

    public SingleTableQueryExecutePlan(){

    }

    public List<SQLExpr> getConditions() {
        return conditions;
    }

    public void setConditions(List<SQLExpr> conditions) {
        this.conditions = conditions;
    }

    public List<String> getColumeNames() {
        return columeNames;
    }

    public HResultSetMetaDataImpl getResultMetaData() {
        return resultMetaData;
    }

    public void setResultMetaData(HResultSetMetaDataImpl resultMetaData) {
        this.resultMetaData = resultMetaData;
    }

    @Override
    public HScannerResultSetImpl executeQuery(HPreparedStatementImpl statement) throws SQLException {
        try {
            HMapping mapping = this.getMapping();
            if (mapping == null) {
                mapping = new HMappingDefaultImpl();
            }

            HBaseConnectionImpl connection = statement.getConnection();

            scan = new Scan();
            this.statement = statement;

            Filter filter = null;
            for (SQLExpr item : conditions) {
                SQLBinaryOpExpr condition = (SQLBinaryOpExpr) item;
                filter = setFilter(condition, filter, true);
            }
            if (filter != null) {
                scan.setFilter(filter);
            }

            HTableInterface htable = connection.getHTable(getTableName());
            ResultScanner scanner = htable.getScanner(scan);

            HScannerResultSetImpl resultSet = new HScannerResultSetImpl(statement, htable, scanner);
            resultSet.setMetaData(resultMetaData);

            return resultSet;
        } catch (SQLException e) {
            throw e;
        } catch (Exception e) {
            throw new SQLException("executeQuery error", e);
        } finally {
            scan = null;
            this.statement = null;
        }
    }

    private Filter setFilter(SQLBinaryOpExpr condition, Filter filter, boolean and) throws IOException, SQLException {
        HMapping mapping = this.getMapping();

        if (condition.getOperator() == SQLBinaryOperator.BooleanAnd) {
            filter = setFilter((SQLBinaryOpExpr) condition.getLeft(), filter, true);
            filter = setFilter((SQLBinaryOpExpr) condition.getRight(), filter, true);
            return filter;
        } else if (condition.getOperator() == SQLBinaryOperator.BooleanOr) {
            filter = setFilter((SQLBinaryOpExpr) condition.getLeft(), filter, false);
            filter = setFilter((SQLBinaryOpExpr) condition.getRight(), filter, false);
            return filter;
        }
       
        String fieldName = ((SQLIdentifierExpr) condition.getLeft()).getName();
        Object value = SQLEvalVisitorUtils.eval(dbType, condition.getRight(), statement.getParameters());

        byte[] bytes = mapping.toBytes(fieldName, value);
        if (mapping.isRow(fieldName)) {
            if (filter == null && condition.getOperator() == SQLBinaryOperator.GreaterThanOrEqual) {
                scan.setStartRow(bytes);
                return null;
            } else if (filter == null && condition.getOperator() == SQLBinaryOperator.LessThan) {
                scan.setStopRow(bytes);
                return null;
            } else {
                CompareOp compareOp = toCompareOp(condition.getOperator());
                RowFilter rowFilter = new RowFilter(compareOp, new BinaryComparator(bytes));

                return setFilter(filter, rowFilter, and);
            }
        } else {
            byte[] qualifier = mapping.getQualifier(fieldName);
            byte[] family = mapping.getFamily(fieldName);

            CompareOp compareOp = toCompareOp(condition.getOperator());

            SingleColumnValueFilter columnFilter = new SingleColumnValueFilter(family, qualifier, compareOp, bytes);
            return setFilter(filter, columnFilter, and);
        }

    }

    CompareOp toCompareOp(SQLBinaryOperator operator) {
        switch (operator) {
            case Equality:
                return CompareOp.EQUAL;
            case NotEqual:
                return CompareOp.NOT_EQUAL;
            case GreaterThan:
                return CompareOp.GREATER;
            case GreaterThanOrEqual:
                return CompareOp.GREATER_OR_EQUAL;
            case LessThan:
                return CompareOp.LESS;
            case LessThanOrEqual:
                return CompareOp.LESS_OR_EQUAL;
            default:
                throw new UnsupportedOperationException("TODO");
        }
    }

    Filter setFilter(Filter parentFilter, Filter filter, boolean and) {
        if (parentFilter == null) {
            return filter;
        } else if (parentFilter instanceof FilterList) {
            FilterList filterList = (FilterList) parentFilter;
            if (and) {
                if (filterList.getOperator() == FilterList.Operator.MUST_PASS_ALL) {
                    filterList.addFilter(filter);
                    return filterList;
                } else {
                    return new FilterList(FilterList.Operator.MUST_PASS_ALL, parentFilter, filter);
                }
            } else {
                if (filterList.getOperator() == FilterList.Operator.MUST_PASS_ONE) {
                    filterList.addFilter(filter);
                    return filterList;
                } else {
                    return new FilterList(FilterList.Operator.MUST_PASS_ONE, parentFilter, filter);
                }
            }
        } else {
            List<Filter> filters = new ArrayList<Filter>();
            filters.add(parentFilter);
            filters.add(filter);
           
            FilterList.Operator filterOp = and ? FilterList.Operator.MUST_PASS_ALL : FilterList.Operator.MUST_PASS_ONE;
            return new FilterList(filterOp, filters);
        }
    }

}
TOP

Related Classes of com.alibaba.druid.hdriver.impl.execute.SingleTableQueryExecutePlan

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.