1// https://github.com/apache/drill/raw/master/logical/src/main/antlr3/org/apache/drill/common/expression/parser/ExprParser.g 2parser grammar ExprParser; 3 4options{ 5 output=AST; 6 language=Java; 7 tokenVocab=ExprLexer; 8 backtrack=true; 9 memoize=true; 10} 11 12 13 14@header { 15/* 16 * Licensed to the Apache Software Foundation (ASF) under one 17 * or more contributor license agreements. See the NOTICE file 18 * distributed with this work for additional information 19 * regarding copyright ownership. The ASF licenses this file 20 * to you under the Apache License, Version 2.0 (the 21 * "License"); you may not use this file except in compliance 22 * with the License. You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33package org.apache.drill.common.expression.parser; 34 35//Explicit import... 36import org.antlr.runtime.BitSet; 37import java.util.*; 38import org.apache.drill.common.expression.*; 39import org.apache.drill.common.expression.PathSegment.NameSegment; 40import org.apache.drill.common.expression.PathSegment.ArraySegment; 41import org.apache.drill.common.types.*; 42import org.apache.drill.common.types.TypeProtos.*; 43import org.apache.drill.common.types.TypeProtos.DataMode; 44import org.apache.drill.common.types.TypeProtos.MajorType; 45import org.apache.drill.common.exceptions.ExpressionParsingException; 46} 47 48@members{ 49 private String fullExpression; 50 private int tokenPos; 51 52 public static void p(String s){ 53 System.out.println(s); 54 } 55 56 public ExpressionPosition pos(Token token){ 57 return new ExpressionPosition(fullExpression, token.getTokenIndex()); 58 } 59 60 @Override 61 public void displayRecognitionError(String[] tokenNames, RecognitionException e) { 62 String hdr = getErrorHeader(e); 63 String msg = getErrorMessage(e, tokenNames); 64 throw new ExpressionParsingException("Expression has syntax error! " + hdr + ":" + msg); 65 } 66} 67 68parse returns [LogicalExpression e] 69 : expression EOF { 70 $e = $expression.e; 71 if(fullExpression == null) fullExpression = $expression.text; 72 tokenPos = $expression.start.getTokenIndex(); 73 } 74 ; 75 76functionCall returns [LogicalExpression e] 77 : Identifier OParen exprList? CParen {$e = FunctionCallFactory.createExpression($Identifier.text, pos($Identifier), $exprList.listE); } 78 ; 79 80convertCall returns [LogicalExpression e] 81 : Convert OParen expression Comma String CParen 82 { $e = FunctionCallFactory.createConvert($Convert.text, $String.text, $expression.e, pos($Convert));} 83 ; 84 85castCall returns [LogicalExpression e] 86 @init{ 87 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 88 ExpressionPosition p = null; 89 } 90 : Cast OParen expression As dataType repeat? CParen 91 { if ($repeat.isRep!=null && $repeat.isRep.compareTo(Boolean.TRUE)==0) 92 $e = FunctionCallFactory.createCast(TypeProtos.MajorType.newBuilder().mergeFrom($dataType.type).setMode(DataMode.REPEATED).build(), pos($Cast), $expression.e); 93 else 94 $e = FunctionCallFactory.createCast($dataType.type, pos($Cast), $expression.e);} 95 ; 96 97repeat returns [Boolean isRep] 98 : Repeat { $isRep = Boolean.TRUE;} 99 ; 100 101dataType returns [MajorType type] 102 : numType {$type =$numType.type;} 103 | charType {$type =$charType.type;} 104 | dateType {$type =$dateType.type;} 105 | booleanType {$type =$booleanType.type;} 106 ; 107 108booleanType returns [MajorType type] 109 : BIT { $type = Types.required(TypeProtos.MinorType.BIT); } 110 ; 111 112numType returns [MajorType type] 113 : INT { $type = Types.required(TypeProtos.MinorType.INT); } 114 | BIGINT { $type = Types.required(TypeProtos.MinorType.BIGINT); } 115 | FLOAT4 { $type = Types.required(TypeProtos.MinorType.FLOAT4); } 116 | FLOAT8 { $type = Types.required(TypeProtos.MinorType.FLOAT8); } 117 | DECIMAL9 OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL9).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); } 118 | DECIMAL18 OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL18).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); } 119 | DECIMAL28DENSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL28DENSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); } 120 | DECIMAL28SPARSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL28SPARSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); } 121 | DECIMAL38DENSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL38DENSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); } 122 | DECIMAL38SPARSE OParen precision Comma scale CParen { $type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.DECIMAL38SPARSE).setMode(DataMode.REQUIRED).setPrecision($precision.value.intValue()).setScale($scale.value.intValue()).build(); } 123 ; 124 125charType returns [MajorType type] 126 : VARCHAR typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARCHAR).setMode(DataMode.REQUIRED).setWidth($typeLen.length.intValue()).build(); } 127 | VARBINARY typeLen {$type = TypeProtos.MajorType.newBuilder().setMinorType(TypeProtos.MinorType.VARBINARY).setMode(DataMode.REQUIRED).setWidth($typeLen.length.intValue()).build();} 128 ; 129 130precision returns [Integer value] 131 : Number {$value = Integer.parseInt($Number.text); } 132 ; 133 134scale returns [Integer value] 135 : Number {$value = Integer.parseInt($Number.text); } 136 ; 137 138dateType returns [MajorType type] 139 : DATE { $type = Types.required(TypeProtos.MinorType.DATE); } 140 | TIMESTAMP { $type = Types.required(TypeProtos.MinorType.TIMESTAMP); } 141 | TIME { $type = Types.required(TypeProtos.MinorType.TIME); } 142 | TIMESTAMPTZ { $type = Types.required(TypeProtos.MinorType.TIMESTAMPTZ); } 143 | INTERVAL { $type = Types.required(TypeProtos.MinorType.INTERVAL); } 144 | INTERVALYEAR { $type = Types.required(TypeProtos.MinorType.INTERVALYEAR); } 145 | INTERVALDAY { $type = Types.required(TypeProtos.MinorType.INTERVALDAY); } 146 ; 147 148typeLen returns [Integer length] 149 : OParen Number CParen {$length = Integer.parseInt($Number.text);} 150 ; 151 152ifStatement returns [LogicalExpression e] 153 @init { 154 IfExpression.Builder s = IfExpression.newBuilder(); 155 } 156 @after { 157 $e = s.build(); 158 } 159 : i1=ifStat {s.setIfCondition($i1.i); s.setPosition(pos($i1.start)); } (elseIfStat { s.setIfCondition($elseIfStat.i); } )* Else expression { s.setElse($expression.e); }End 160 ; 161 162ifStat returns [IfExpression.IfCondition i] 163 : If e1=expression Then e2=expression { $i = new IfExpression.IfCondition($e1.e, $e2.e); } 164 ; 165elseIfStat returns [IfExpression.IfCondition i] 166 : Else If e1=expression Then e2=expression { $i = new IfExpression.IfCondition($e1.e, $e2.e); } 167 ; 168 169caseStatement returns [LogicalExpression e] 170 @init { 171 IfExpression.Builder s = IfExpression.newBuilder(); 172 } 173 @after { 174 $e = s.build(); 175 } 176 : Case (caseWhenStat {s.setIfCondition($caseWhenStat.e); }) + caseElseStat { s.setElse($caseElseStat.e); } End 177 ; 178 179caseWhenStat returns [IfExpression.IfCondition e] 180 : When e1=expression Then e2=expression {$e = new IfExpression.IfCondition($e1.e, $e2.e); } 181 ; 182 183caseElseStat returns [LogicalExpression e] 184 : Else expression {$e = $expression.e; } 185 ; 186 187exprList returns [List<LogicalExpression> listE] 188 @init{ 189 $listE = new ArrayList<LogicalExpression>(); 190 } 191 : e1=expression {$listE.add($e1.e); } (Comma e2=expression {$listE.add($e2.e); } )* 192 ; 193 194expression returns [LogicalExpression e] 195 : ifStatement {$e = $ifStatement.e; } 196 | caseStatement {$e = $caseStatement.e; } 197 | condExpr {$e = $condExpr.e; } 198 ; 199 200condExpr returns [LogicalExpression e] 201 : orExpr {$e = $orExpr.e; } 202 ; 203 204orExpr returns [LogicalExpression e] 205 @init{ 206 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 207 ExpressionPosition p = null; 208 } 209 @after{ 210 if(exprs.size() == 1){ 211 $e = exprs.get(0); 212 }else{ 213 $e = FunctionCallFactory.createBooleanOperator("or", p, exprs); 214 } 215 } 216 : a1=andExpr { exprs.add($a1.e); p = pos( $a1.start );} (Or a2=andExpr { exprs.add($a2.e); })* 217 ; 218 219andExpr returns [LogicalExpression e] 220 @init{ 221 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 222 ExpressionPosition p = null; 223 } 224 @after{ 225 if(exprs.size() == 1){ 226 $e = exprs.get(0); 227 }else{ 228 $e = FunctionCallFactory.createBooleanOperator("and", p, exprs); 229 } 230 } 231 : e1=equExpr { exprs.add($e1.e); p = pos( $e1.start ); } ( And e2=equExpr { exprs.add($e2.e); })* 232 ; 233 234equExpr returns [LogicalExpression e] 235 @init{ 236 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 237 List<String> cmps = new ArrayList(); 238 ExpressionPosition p = null; 239 } 240 @after{ 241 $e = FunctionCallFactory.createByOp(exprs, p, cmps); 242 } 243 : r1=relExpr { exprs.add($r1.e); p = pos( $r1.start ); 244 } ( cmpr= ( Equals | NEquals ) r2=relExpr {exprs.add($r2.e); cmps.add($cmpr.text); })* 245 ; 246 247relExpr returns [LogicalExpression e] 248 : left=addExpr {$e = $left.e; } (cmpr = (GTEquals | LTEquals | GT | LT) right=addExpr {$e = FunctionCallFactory.createExpression($cmpr.text, pos($left.start), $left.e, $right.e); } )? 249 ; 250 251addExpr returns [LogicalExpression e] 252 @init{ 253 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 254 List<String> ops = new ArrayList(); 255 ExpressionPosition p = null; 256 } 257 @after{ 258 $e = FunctionCallFactory.createByOp(exprs, p, ops); 259 } 260 : m1=mulExpr {exprs.add($m1.e); p = pos($m1.start); } ( op=(Plus|Minus) m2=mulExpr {exprs.add($m2.e); ops.add($op.text); })* 261 ; 262 263mulExpr returns [LogicalExpression e] 264 @init{ 265 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 266 List<String> ops = new ArrayList(); 267 ExpressionPosition p = null; 268 } 269 @after{ 270 $e = FunctionCallFactory.createByOp(exprs, p, ops); 271 } 272 : p1=xorExpr {exprs.add($p1.e); p = pos($p1.start);} (op=(Asterisk|ForwardSlash|Percent) p2=xorExpr {exprs.add($p2.e); ops.add($op.text); } )* 273 ; 274 275xorExpr returns [LogicalExpression e] 276 @init{ 277 List<LogicalExpression> exprs = new ArrayList<LogicalExpression>(); 278 List<String> ops = new ArrayList(); 279 ExpressionPosition p = null; 280 } 281 @after{ 282 $e = FunctionCallFactory.createByOp(exprs, p, ops); 283 } 284 : u1=unaryExpr {exprs.add($u1.e); p = pos($u1.start);} (Caret u2=unaryExpr {exprs.add($u2.e); ops.add($Caret.text);} )* 285 ; 286 287unaryExpr returns [LogicalExpression e] 288 : sign=(Plus|Minus)? Number {$e = ValueExpressions.getNumericExpression($sign.text, $Number.text, pos(($sign != null) ? $sign : $Number)); } 289 | Minus atom {$e = FunctionCallFactory.createExpression("u-", pos($Minus), $atom.e); } 290 | Excl atom {$e= FunctionCallFactory.createExpression("!", pos($Excl), $atom.e); } 291 | atom {$e = $atom.e; } 292 ; 293 294atom returns [LogicalExpression e] 295 : Bool {$e = new ValueExpressions.BooleanExpression($Bool.text, pos($Bool)); } 296 | lookup {$e = $lookup.e; } 297 ; 298 299pathSegment returns [NameSegment seg] 300 : s1=nameSegment {$seg = $s1.seg;} 301 ; 302 303nameSegment returns [NameSegment seg] 304 : QuotedIdentifier ( (Period s1=pathSegment) | s2=arraySegment)? {$seg = new NameSegment($QuotedIdentifier.text, ($s1.seg == null ? $s2.seg : $s1.seg) ); } 305 | Identifier ( (Period s1=pathSegment) | s2=arraySegment)? {$seg = new NameSegment($Identifier.text, ($s1.seg == null ? $s2.seg : $s1.seg) ); } 306 ; 307 308arraySegment returns [PathSegment seg] 309 : OBracket Number CBracket ( (Period s1=pathSegment) | s2=arraySegment)? {$seg = new ArraySegment($Number.text, ($s1.seg == null ? $s2.seg : $s1.seg) ); } 310 ; 311 312 313lookup returns [LogicalExpression e] 314 : functionCall {$e = $functionCall.e ;} 315 | convertCall {$e = $convertCall.e; } 316 | castCall {$e = $castCall.e; } 317 | pathSegment {$e = new SchemaPath($pathSegment.seg, pos($pathSegment.start) ); } 318 | String {$e = new ValueExpressions.QuotedString($String.text, pos($String) ); } 319 | OParen expression CParen {$e = $expression.e; } 320 | SingleQuote Identifier SingleQuote {$e = new SchemaPath($Identifier.text, pos($Identifier) ); } 321 ; 322 323 324 325