phoenix select语句的解析流程

客户端调用phoenix的jdbc接口,代码如下:

    Connection conn = DriverManager.getConnection(url);
    Statement statement = conn.createStatement();
    ResultSet rset = statement.executeQuery("select a from test1");  
    while (rset.next()) {
          System.out.println(rset.toString());
    }
    rset.close();
    statement.close();
    conn.close();

在PhoenixStatement类中,executeQuery(string sql)方法用来初步处理sql语句字符串

    public ResultSet executeQuery(String sql) throws SQLException {
        if (logger.isDebugEnabled()) {
            logger.debug("Execute query: " + sql);
        }
        CompilableStatement stmt = parseStatement(sql);
        if (stmt.getOperation().isMutation()) {
            throw new ExecuteQueryNotApplicableException(sql);
        }
        return executeQuery(stmt);
}
其中, parseStatement(sql)语句负责将sql字符串转换为statement对象,其代码为:

    protected CompilableStatement parseStatement(String sql) throws SQLException {
        PhoenixStatementParser parser = null;
        try {
            parser = new PhoenixStatementParser(sql, new ExecutableNodeFactory());
        } catch (IOException e) {
            throw ServerUtil.parseServerException(e);
        }
        CompilableStatement statement = parser.parseStatement();
        return statement;
}
其核心的实现过程在
parser.parseStatement
中执行,这部分是由antlr实现,具体细节可以参考antlr相关文档。

在phoenix中,selectstatement类的主要成员变量如下:

    private final List<TableNode> fromTable;  
    private final HintNode hint;
    private final boolean isDistinct;
    private final List<AliasedNode> select;
    private final ParseNode where;
    private final List<ParseNode> groupBy;
    private final ParseNode having;
    private final List<OrderByNode> orderBy;
    private final LimitNode limit;
    private final int bindCount;
    private final boolean isAggregate;
    private final boolean hasSequence;
通过parseStatement函数,将sql语句中的各个语句块解析成statement对象中的一个个node

解析成statement的成员后,将调用executeQuery(final CompilableStatement stmt),进行执行,这也是核心部分,其核心代码为:

    //生成查询计划  
    QueryPlan plan = stmt.compilePlan(PhoenixStatement.this, Sequence.ValueOp.RESERVE_SEQUENCE);  
    //检查是否能使用索引表优化查询  
    plan = connection.getQueryServices().getOptimizer().optimize(  
    PhoenixStatement.this, plan);  
    // this will create its own trace internally, so we don't wrap this  
    // whole thing in tracing  
    //创建hbase的scnner  
    ResultIterator resultIterator = plan.iterator();  
    if (logger.isDebugEnabled()) {  
        String explainPlan = QueryUtil.getExplainPlan(resultIterator);  
        logger.debug("Explain plan: " + explainPlan);  
    }  
    //创建一个resultset对象  
    PhoenixResultSet rs = newResultSet(resultIterator, plan.getProjector());  
    //将rs加入reslutSets队列  
    resultSets.add(rs);  
    //保存此次的查询计划  
    setLastQueryPlan(plan);  
    //保存此次的resultset  
    setLastResultSet(rs);  
    //将update次数统计清零  
    setLastUpdateCount(NO_UPDATE);  
    //保存此次查询的操作类型  
    setLastUpdateOperation(stmt.getOperation());  
    //返回resulteset对象给客户端  
    return rs;  
在客户端代码的rset.next()函数实际上调用的是phoenixResultSets类中的
    public boolean next() throws SQLException {
        checkOpen();
        try {
            currentRow = scanner.next();
        } catch (RuntimeException e) {
            // FIXME: Expression.evaluate does not throw SQLException
            // so this will unwrap throws from that.
            if (e.getCause() instanceof SQLException) {
                throw (SQLException) e.getCause();
            }
            throw e;
        }
        return currentRow != null;
    }
触发了hbase的scanner执行next,从hbase中获取数据








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值