View Javadoc

1   /*
2    * Copyright (c) 2011.  The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.hbql.parser;
22  
23  import org.antlr.runtime.ANTLRStringStream;
24  import org.antlr.runtime.CommonTokenStream;
25  import org.antlr.runtime.Lexer;
26  import org.antlr.runtime.RecognitionException;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.apache.expreval.client.InternalErrorException;
30  import org.apache.expreval.client.LexerRecognitionException;
31  import org.apache.expreval.client.NullColumnValueException;
32  import org.apache.expreval.client.ResultMissingColumnException;
33  import org.apache.expreval.expr.ExpressionTree;
34  import org.apache.expreval.expr.node.GenericValue;
35  import org.apache.hadoop.hbase.hbql.antlr.HBqlLexer;
36  import org.apache.hadoop.hbase.hbql.antlr.HBqlParser;
37  import org.apache.hadoop.hbase.hbql.client.HBqlException;
38  import org.apache.hadoop.hbase.hbql.impl.ParseException;
39  import org.apache.hadoop.hbase.hbql.mapping.Mapping;
40  import org.apache.hadoop.hbase.hbql.mapping.MappingContext;
41  import org.apache.hadoop.hbase.hbql.statement.HBqlStatement;
42  import org.apache.hadoop.hbase.hbql.statement.args.WithArgs;
43  import org.apache.hadoop.hbase.hbql.statement.select.SelectExpressionContext;
44  
45  import java.util.List;
46  import java.util.Map;
47  
48  public class ParserUtil {
49  
50      private static final Log log = LogFactory.getLog(ParserUtil.class.getName());
51  
52      public static HBqlParser newHBqlParser(final String sql) throws ParseException {
53          try {
54              log.debug("Parsing: " + sql);
55              final Lexer lex = new HBqlLexer(new ANTLRStringStream(sql));
56              final CommonTokenStream tokens = new CommonTokenStream(lex);
57              return new HBqlParser(tokens);
58          }
59          catch (LexerRecognitionException e) {
60              throw new ParseException(e.getRecognitionExecption(), e.getMessage());
61          }
62      }
63  
64      public static ExpressionTree parseWhereExpression(final String sql,
65                                                        final MappingContext mappingContext) throws HBqlException {
66          try {
67              return getExpressionTree(sql, mappingContext);
68          }
69          catch (RecognitionException e) {
70              e.printStackTrace();
71              throw new HBqlException("Error parsing: " + sql);
72          }
73      }
74  
75      public static ExpressionTree getExpressionTree(final String str,
76                                                     final MappingContext mappingContext) throws HBqlException,
77                                                                                                 RecognitionException {
78          final Mapping mapping = mappingContext.getMapping();
79  
80          final Map<String, ExpressionTree> map = mapping.getEvalMap();
81          ExpressionTree expressionTree = map.get(str);
82  
83          if (expressionTree == null) {
84              final HBqlParser parser = ParserUtil.newHBqlParser(str);
85              expressionTree = parser.nodescWhereExpr();
86              expressionTree.setMappingContext(mappingContext);
87              mapping.addToExpressionTreeCache(str, expressionTree);
88          }
89          else {
90              expressionTree.reset();
91          }
92          return expressionTree;
93      }
94  
95  
96      public static Object parseExpression(final String sql) throws HBqlException {
97          try {
98              final HBqlParser parser = ParserUtil.newHBqlParser(sql);
99              final GenericValue valueExpr = parser.exprValue();
100             valueExpr.validateTypes(null, false);
101             return valueExpr.getValue(null, null);
102         }
103         catch (ResultMissingColumnException e) {
104             // No column refs should be missing
105             throw new InternalErrorException("Missing column: " + e.getMessage());
106         }
107         catch (NullColumnValueException e) {
108             throw new InternalErrorException("Null value: " + e.getMessage());
109         }
110         catch (RecognitionException e) {
111             e.printStackTrace();
112             throw new ParseException(e, sql);
113         }
114     }
115 
116     public static SelectExpressionContext parseSelectElement(final String sql) throws HBqlException {
117         try {
118             final HBqlParser parser = ParserUtil.newHBqlParser(sql);
119             final SelectExpressionContext elem = (SelectExpressionContext)parser.selectElem();
120             elem.setMappingContext(null);
121             return elem;
122         }
123         catch (RecognitionException e) {
124             e.printStackTrace();
125             throw new ParseException(e, sql);
126         }
127     }
128 
129     public static Object evaluateSelectElement(final SelectExpressionContext elem) throws HBqlException {
130         return elem.getValue(null, null);
131     }
132 
133     public static WithArgs parseWithClause(final String sql) throws ParseException {
134         try {
135             final HBqlParser parser = ParserUtil.newHBqlParser(sql);
136             return parser.withClause();
137         }
138         catch (RecognitionException e) {
139             e.printStackTrace();
140             throw new ParseException(e, sql);
141         }
142     }
143 
144     public static List<HBqlStatement> parseConsoleStatements(final String sql) throws HBqlException {
145         try {
146             final HBqlParser parser = ParserUtil.newHBqlParser(sql);
147             final List<HBqlStatement> stmts = parser.consoleStatements();
148             for (final HBqlStatement stmt : stmts)
149                 stmt.validate();
150             return stmts;
151         }
152         catch (LexerRecognitionException e) {
153             throw new ParseException(e.getRecognitionExecption(), sql);
154         }
155         catch (RecognitionException e) {
156             throw new ParseException(e, sql);
157         }
158     }
159 
160     public static HBqlStatement parseHBqlStatement(final String sql) throws HBqlException {
161         try {
162             final HBqlParser parser = ParserUtil.newHBqlParser(sql + ";");
163             final HBqlStatement stmt = parser.hbqlStatement();
164             stmt.validate();
165             return stmt;
166         }
167         catch (LexerRecognitionException e) {
168             throw new ParseException(e.getRecognitionExecption(), sql);
169         }
170         catch (RecognitionException e) {
171             throw new ParseException(e, sql);
172         }
173     }
174 }