| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- %{
- //
- // Parser.jay
- //
- // Author:
- // Juraj Skripsky ([email protected])
- //
- // (C) 2004 HotFeet GmbH (http://www.hotfeet.ch)
- //
- using System;
- using System.Collections;
- using System.Data;
- namespace Mono.Data.SqlExpressions {
- internal class Parser {
- static Parser ()
- {
- if (Environment.GetEnvironmentVariable ("MONO_DEBUG_SQLEXPRESSIONS") != null)
- yacc_verbose_flag = 2;
- }
- bool cacheAggregationResults = false;
- DataRow[] aggregationRows = null;
- static int yacc_verbose_flag;
-
- //called by DataTable.Select
- //called by DataColumn.set_Expression //FIXME: enable cache in this case?
- public Parser () {
- ErrorOutput = System.IO.TextWriter.Null;
- cacheAggregationResults = true;
- }
-
- //called by DataTable.Compute
- public Parser (DataRow[] aggregationRows)
- {
- ErrorOutput = System.IO.TextWriter.Null;
- this.aggregationRows = aggregationRows;
- }
-
- public IExpression Compile (string sqlExpr)
- {
- try {
- Tokenizer tokenizer = new Tokenizer (sqlExpr);
- if (yacc_verbose_flag > 1)
- return (IExpression) yyparse (tokenizer,
- new yydebug.yyDebugSimple ());
- else
- return (IExpression) yyparse (tokenizer);
- } catch (yyParser.yyException e) {
- throw new SyntaxErrorException (String.Format ("Expression '{0}' is invalid.", sqlExpr));
- }
- }
- %}
- %token PAROPEN PARCLOSE
- %token AND OR
- %token NOT
- %token TRUE FALSE
- %token NULL
- %token PARENT CHILD
- %token EQ LT GT
- %token PLUS MINUS
- %token MUL DIV MOD
- %token DOT COMMA
- %token IS IN LIKE
- %token COUNT SUM AVG MAX MIN STDEV VAR
- %token IIF SUBSTRING ISNULL LEN TRIM CONVERT
- %token StringLiteral NumberLiteral DateLiteral
- %token Identifier
- %token FunctionName
- %start Expr
- %left OR
- %left AND
- %left NOT
- %left EQ LT GT
- %left PLUS MINUS
- %left MUL DIV MOD
- %left UMINUS
- %%
- Expr
- : BoolExpr
- | ArithExpr
- ;
- BoolExpr
- : PAROPEN BoolExpr PARCLOSE
- {
- $$ = (IExpression)$2;
- }
- | BoolExpr AND BoolExpr
- {
- $$ = new BoolOperation (Operation.AND, (IExpression)$1, (IExpression)$3);
- }
- | BoolExpr OR BoolExpr
- {
- $$ = new BoolOperation (Operation.OR, (IExpression)$1, (IExpression)$3);
- }
- | NOT BoolExpr
- {
- $$ = new Negation ((IExpression)$2);
- }
- | Predicate
- ;
- Predicate
- : CompPredicate
- | IsPredicate
- | LikePredicate
- | InPredicate
- ;
- CompPredicate
- : ArithExpr CompOp ArithExpr
- {
- $$ = new Comparison ((Operation)$2, (IExpression)$1, (IExpression)$3);
- }
- ;
- CompOp
- : EQ { $$ = Operation.EQ; }
- | NE { $$ = Operation.NE; }
- | LT { $$ = Operation.LT; }
- | GT { $$ = Operation.GT; }
- | LE { $$ = Operation.LE; }
- | GE { $$ = Operation.GE; }
- ;
- LE : LT EQ; // <=
- NE : LT GT; // <>
- GE : GT EQ; // >=
-
- ArithExpr
- : PAROPEN ArithExpr PARCLOSE
- {
- $$ = (IExpression)$2;
- }
- | ArithExpr MUL ArithExpr
- {
- $$ = new ArithmeticOperation (Operation.MUL, (IExpression)$1, (IExpression)$3);
- }
- | ArithExpr DIV ArithExpr
- {
- $$ = new ArithmeticOperation (Operation.DIV, (IExpression)$1, (IExpression)$3);
- }
- | ArithExpr MOD ArithExpr
- {
- $$ = new ArithmeticOperation (Operation.MOD, (IExpression)$1, (IExpression)$3);
- }
- | ArithExpr PLUS ArithExpr
- {
- $$ = new ArithmeticOperation (Operation.ADD, (IExpression)$1, (IExpression)$3);
- }
- | ArithExpr MINUS ArithExpr
- {
- $$ = new ArithmeticOperation (Operation.SUB, (IExpression)$1, (IExpression)$3);
- }
- | MINUS ArithExpr %prec UMINUS
- {
- $$ = new Negative ((IExpression)$2);
- }
- | Function
- | Value
- ;
- Value
- : LiteralValue
- | SingleColumnValue
- ;
- LiteralValue
- : StringLiteral { $$ = new Literal ($1); }
- | NumberLiteral { $$ = new Literal ($1); }
- | DateLiteral { $$ = new Literal ($1); }
- | BoolLiteral
- ;
- BoolLiteral
- : TRUE { $$ = new Literal (true); }
- | FALSE { $$ = new Literal (false); }
- ;
- SingleColumnValue
- : LocalColumnValue
- | ParentColumnValue
- ;
- MultiColumnValue
- : LocalColumnValue
- | ChildColumnValue
- ;
- LocalColumnValue
- : ColumnName
- {
- $$ = new ColumnReference ((string)$1);
- }
- ;
- ParentColumnValue
- : PARENT DOT ColumnName
- {
- $$ = new ColumnReference (ReferencedTable.Parent, null, (string)$3);
- }
- | PARENT PAROPEN RelationName PARCLOSE DOT ColumnName
- {
- $$ = new ColumnReference (ReferencedTable.Parent, (string)$3, (string)$6);
- }
- ;
- ChildColumnValue
- : CHILD DOT ColumnName
- {
- $$ = new ColumnReference (ReferencedTable.Child, null, (string)$3);
- }
- | CHILD PAROPEN RelationName PARCLOSE DOT ColumnName
- {
- $$ = new ColumnReference (ReferencedTable.Child, (string)$3, (string)$6);
- }
- ;
-
- ColumnName
- : Identifier;
-
- RelationName
- : Identifier;
- Function
- : CalcFunction
- | AggFunction
- ;
- AggFunction
- : AggFunctionName PAROPEN MultiColumnValue PARCLOSE
- {
- $$ = new Aggregation (cacheAggregationResults, aggregationRows, (AggregationFunction)$1, (ColumnReference)$3);
- }
- ;
- AggFunctionName
- : COUNT { $$ = AggregationFunction.Count; }
- | SUM { $$ = AggregationFunction.Sum; }
- | AVG { $$ = AggregationFunction.Avg; }
- | MAX { $$ = AggregationFunction.Max; }
- | MIN { $$ = AggregationFunction.Min; }
- | STDEV { $$ = AggregationFunction.StDev; }
- | VAR { $$ = AggregationFunction.Var; }
- ;
- CalcFunction
- : IIF PAROPEN BoolExpr COMMA Expr COMMA Expr PARCLOSE
- {
- $$ = new IifFunction ((IExpression)$3, (IExpression)$5, (IExpression)$7);
- }
- | SUBSTRING PAROPEN Expr COMMA NumberLiteral COMMA NumberLiteral PARCLOSE
- {
- long arg1 = (long) $5;
- long arg2 = (long) $7;
- $$ = new SubstringFunction ((IExpression)$3, Convert.ToInt32(arg1), Convert.ToInt32(arg2));
- }
- | ISNULL PAROPEN Expr COMMA Expr PARCLOSE
- {
- $$ = new IsNullFunction ((IExpression)$3, (IExpression)$5);
- }
- | LEN PAROPEN Expr PARCLOSE
- {
- $$ = new LenFunction ((IExpression)$3);
- }
- | TRIM PAROPEN Expr PARCLOSE
- {
- $$ = new TrimFunction ((IExpression)$3);
- }
- | CONVERT PAROPEN Expr COMMA TypeSpecifier PARCLOSE
- {
- $$ = new ConvertFunction ((IExpression)$3, (string)$5);
- }
- ;
- TypeSpecifier
- : StringLiteral
- | Identifier
- ;
- IsPredicate
- : SingleColumnValue IS NULL
- {
- $$ = new Comparison (Operation.EQ, (IExpression)$1, new Literal (null));
- }
- | SingleColumnValue IS NOT NULL
- {
- $$ = new Comparison (Operation.NE, (IExpression)$1, new Literal (null));
- }
- ;
- LikePredicate
- : ArithExpr LIKE StringLiteral
- {
- $$ = new Like ((IExpression)$1, (string)$3);
- }
- | ArithExpr NOT LIKE StringLiteral
- {
- $$ = new Negation (new Like ((IExpression)$1, (string)$3));
- }
- ;
- InPredicate
- : SingleColumnValue IN InPredicateValue
- {
- $$ = new In ((IExpression)$1, (IList)$3);
- }
- | SingleColumnValue NOT IN InPredicateValue
- {
- $$ = new Negation (new In ((IExpression)$1, (IList)$4));
- }
- ;
- InPredicateValue
- : PAROPEN InValueList PARCLOSE { $$ = $2; }
- ;
- InValueList
- : LiteralValue
- {
- $$ = new ArrayList();
- ((IList)$$).Add ($1);
- }
- | InValueList COMMA LiteralValue
- {
- ((IList)($$ = $1)).Add ($3);
- }
- ;
- %%
- }
|