public static Expression <Func <T, bool> > GetCriteriaWhere <T, T2>(Expression <Func <T, object> > e, OperationExpression selectedOperator, object fieldValue) { string name = GetOperand(e); return(GetCriteriaWhere <T, T2>(name, selectedOperator, fieldValue)); }
public static Expression <Func <T, bool> > GetCriteriaWhere <T, T2>(string fieldName, OperationExpression selectedOperator, object fieldValue) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); PropertyDescriptor prop = GetProperty(props, fieldName, true); var parameter = Expression.Parameter(typeof(T)); var expressionParameter = GetMemberExpression <T>(parameter, fieldName); if (prop != null && fieldValue != null) { switch (selectedOperator) { case OperationExpression.Any: return(Any <T, T2>(fieldValue, parameter, expressionParameter)); default: throw new Exception("Not implement Operation"); } } Expression <Func <T, bool> > filter = x => true; return(filter); }
private static CombinationExpression GetPredefinedFilter() { var filterExpression = new CombinationExpression(); var filterExpressions = filterExpression.Expressions; var hpGreaterThen200Expression = new OperationExpression() { PropertyName = "HP", FilterOperation = FilterOperation.GreaterThanOrEqual, Value = 200 }; filterExpressions.Add(hpGreaterThen200Expression); var automaticTransmissionExpression = new OperationExpression() { PropertyName = "AutomaticTransmission", FilterOperation = FilterOperation.Equal, Value = true }; filterExpressions.Add(automaticTransmissionExpression); var sportsCategoryExpression = new OperationExpression() { PropertyName = "StartSaleDate", FilterOperation = FilterOperation.GreaterThanOrEqual, Value = new DateTime(2011, 1, 1) }; filterExpressions.Add(sportsCategoryExpression); var brandOrExpression = new CombinationExpression(); brandOrExpression.FilterCombination = FilterCombination.Or; var brandExpressions = brandOrExpression.Expressions; var brandEqualMercedesBenzExpression = new OperationExpression() { PropertyName = "Brand", FilterOperation = FilterOperation.EqualText, Value = "Mercedes-Benz" }; brandExpressions.Add(brandEqualMercedesBenzExpression); var brandEqualAudiExpression = new OperationExpression() { PropertyName = "Brand", FilterOperation = FilterOperation.EqualText, Value = "Audi" }; brandExpressions.Add(brandEqualAudiExpression); filterExpressions.Add(brandOrExpression); return filterExpression; }
/// <summary> /// visit operation Selection /// </summary> /// <param name="expression"></param> public void Visit(OperationExpression expression) { VisitorEventArgs <T> args = new VisitorEventArgs <T>(currentNode: expression, stack: _stack); // call the event VisitingOperationExpression(this, args); // visit subnodes from left to right if (expression.Operator.Arguments >= 1) { Visit(expression.LeftOperand); } if (expression.Operator.Arguments >= 2) { Visit(expression.RightOperand); } // call the event VisitedOperationExpression(this, args); }
public static Expression <Func <T, bool> > GetCriteriaWhere <T>(string fieldName, OperationExpression selectedOperator, object fieldValue) { var props = TypeDescriptor.GetProperties(typeof(T)); var prop = GetProperty(props, fieldName, true); var parameter = Expression.Parameter(typeof(T)); var expressionParameter = GetMemberExpression <T>(parameter, fieldName); if (prop != null && fieldValue != null) { BinaryExpression body = null; switch (selectedOperator) { case OperationExpression.equal: body = Expression.Equal(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.notequal: body = Expression.NotEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.less: body = Expression.LessThan(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.lessorequal: body = Expression.LessThanOrEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.greater: body = Expression.GreaterThan(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.greaterorequal: body = Expression.GreaterThanOrEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.contains: var contains = typeof(string).GetMethod("Contains", new[] { typeof(string) }); var bodyLike = Expression.Call(expressionParameter, contains, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(bodyLike, parameter)); case OperationExpression.endwith: var endswith = typeof(string).GetMethod("EndsWith", new[] { typeof(string) }); var bodyendwith = Expression.Call(expressionParameter, endswith, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(bodyendwith, parameter)); case OperationExpression.beginwith: var startswith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); var bodystartswith = Expression.Call(expressionParameter, startswith, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(bodystartswith, parameter)); case OperationExpression.includes: return(Includes <T>(fieldValue, parameter, expressionParameter, prop.PropertyType)); case OperationExpression.between: return(Between <T>(fieldValue, parameter, expressionParameter, prop.PropertyType)); default: throw new Exception("Not implement Operation"); } } else { Expression <Func <T, bool> > filter = x => true; return(filter); } }
// Swap Visitor?... allows you to replace the parameters of the concatenated expressions with the parameter of one of them?... // ExpressionHelper allows you to create all the necessary expressions and concatenate them with an and/or... public static Expression <Func <T, bool> > GetCriteriaWhere <T>(string fieldName, OperationExpression selectedOperator, object fieldValue) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T)); PropertyDescriptor prop = GetProperty(props, fieldName, true); var parameter = Expression.Parameter(typeof(T)); var expressionParameter = GetMemberExpression <T>(parameter, fieldName); if (prop != null && fieldValue != null) { BinaryExpression body = null; switch (selectedOperator) { case OperationExpression.Equals: body = Expression.Equal(expressionParameter, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.NotEquals: body = Expression.NotEqual(expressionParameter, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.Minor: body = Expression.LessThan(expressionParameter, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.MinorEquals: body = Expression.LessThanOrEqual(expressionParameter, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.Mayor: body = Expression.GreaterThan(expressionParameter, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.MayorEquals: body = Expression.GreaterThanOrEqual(expressionParameter, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(body, parameter)); case OperationExpression.Like: MethodInfo contains = typeof(string).GetMethod("Contains"); var bodyLike = Expression.Call(expressionParameter, contains, Expression.Constant(fieldValue, prop.PropertyType)); return(Expression.Lambda <Func <T, bool> >(bodyLike, parameter)); case OperationExpression.Contains: return(Contains <T>(fieldValue, parameter, expressionParameter)); default: throw new Exception("Not implement Operation"); } } else { Expression <Func <T, bool> > filter = x => true; return(filter); } }
public ExpressionValue Evaluate(Expression exp, Environment env) { if (exp == null) { return(new ExpressionValue(ExpressionValueType.BOOLEAN, false)); } switch (exp.kind) { case (ExpressionType.FUNCTION): { FunctionExpression ex = exp as FunctionExpression; return(this.vm.ExecuteFunction(ex)); } case (ExpressionType.FUNCT_DECL): { FunctionExpression decl = exp as FunctionExpression; return(new ExpressionValue(ExpressionValueType.FUNCTION, decl.function)); } case (ExpressionType.OBJECT): { return(new ExpressionValue(ExpressionValueType.OBJECT)); } case (ExpressionType.GET_OBJ): { AccessKeyExpression get = exp as AccessKeyExpression; List <string> accessor = get.AccessObj; ExpressionValue v = env.Get(accessor [0]) as ExpressionValue; for (int i = 1; i < accessor.Count; i++) { v = v.GetProperty(accessor [i]); } return(v); } case (ExpressionType.IDENTIFIER): { TokenExpression tok = exp as TokenExpression; string id = tok.token.Value; return(env.Get(id) as ExpressionValue); } case (ExpressionType.BOOL): { return(exp.value); } case (ExpressionType.STRING): { return(exp.value); } case (ExpressionType.INTEGER): { return(exp.value); } case (ExpressionType.ADD): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); if (v1.IsString) { return(new ExpressionValue(ExpressionValueType.STRING, v2.String + v1.String)); } else { return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number + v2.Number)); } } case (ExpressionType.SUBS): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number - v2.Number)); } case (ExpressionType.MUL): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number * v2.Number)); } case (ExpressionType.DIV): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number / v2.Number)); } case (ExpressionType.AND): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, v1.Bool && v2.Bool)); } case (ExpressionType.OR): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, v1.Bool || v2.Bool)); } case (ExpressionType.EQUAL): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, (v1.Bool == v2.Bool) && (v1.Number == v2.Number) && (v1.String == v2.String))); } case (ExpressionType.DISEQUAL): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, (v1.Bool != v2.Bool) && (v1.Number != v2.Number) && (v1.String != v2.String))); } case (ExpressionType.LESS): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.BOOLEAN, v1.Number < v2.Number)); } case (ExpressionType.GREATER): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number > v2.Number)); } case (ExpressionType.LESS_OR_EQUAL): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number <= v2.Number)); } case (ExpressionType.GREATER_OR_EQUAL): { OperationExpression op = exp as OperationExpression; ExpressionValue v1 = this.Evaluate(op.lhs, env); ExpressionValue v2 = this.Evaluate(op.rhs, env); return(new ExpressionValue(ExpressionValueType.NUMBER, v1.Number >= v2.Number)); } default: return(null); } }
//constant: // Integer // Float // String // Boolean //symbol: // ReplacementSymbol // Symbol //value: // constant // symbol // operation // scope //operation: value Operator value //list-expression: value-source , value-source //scope: StartScope value-source EndScope //value-source: // value // scope // function // operation //function: symbol StartScope list-expression EndScope | symbol StartScope value-source EndScope public static Expression Parse(List <Token> tokens) { if (tokens == null || tokens.None()) { return(new NullExpression()); } var remainder = tokens.ToList(); Expression program = null; while (remainder.Any()) { Production parsed = null; var current = remainder.First(); switch (current.TokenClass) { case TokenClass.StartScope: parsed = new ScopedExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new SeparatedExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new ErrorExpression().Parse(program, remainder); break; case TokenClass.Whitespace: parsed = new WhitespaceExpression().Parse(remainder); break; case TokenClass.Symbol: parsed = new OperationExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new FunctionExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new SymbolExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new ErrorExpression().Parse(program, remainder); break; case TokenClass.ReplacementSymbol: parsed = new OperationExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new ReplacementSymbolExpression().Parse(remainder); break; case TokenClass.Float: case TokenClass.Integer: parsed = new OperationExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = NumericExpression.TryParseNumeric(remainder); break; case TokenClass.String: parsed = new OperationExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new StringExpression().Parse(remainder); break; case TokenClass.Boolean: parsed = new OperationExpression().Parse(remainder); if (parsed.Expression != null) { break; } parsed = new BooleanExpression().Parse(remainder); break; case TokenClass.Operator: parsed = NumericExpression.TryParseNumeric(remainder); if (parsed.Expression != null) { break; } parsed = new OperationExpression().Parse(program, remainder); if (parsed.Expression != null) { break; } parsed = new ErrorExpression().Parse(program, remainder); break; case TokenClass.Error: throw new Exception("Unexpected sequence: " + remainder.First().Lexeme); default: throw new ArgumentOutOfRangeException(); } if (parsed.Expression != null && !(parsed.Expression is WhitespaceExpression)) { program = parsed.Expression; } remainder = parsed.RemainingTokens; } if (program == null || remainder.Any()) { throw new ParserException(remainder.Select(c => c.Lexeme).StringConcat()); } return(program); }
/// <summary> /// Performing operation or function under indicated index /// </summary> /// <param name="listE"> list of token elements </param> /// <param name="index"> index of the element </param> /// <returns> simplified input </returns> private static List<Element> Simplify(List<Element> listE, int index) { if (listE[index].Type == C.Operation) // if it is an operation { if (index > 0 && index < listE.Count - 1) // if we can perform the operation { if (listE[index - 1].GetNumber() != null && listE[index + 1].GetNumber() != null) { // Creating a new element Number n = new OperationExpression(listE[index - 1].GetNumber(), listE[index].GetOperation(), listE[index + 1].GetNumber()); // Replacing the elements listE.Insert(index - 1, n); listE.RemoveRange(index, 3); } } } else // if it is a function { if (index < listE.Count - 1) // if we can perorm the function { if (listE[index + 1].GetNumber() != null) { // Creating a new element Number n = new FunctionExpression(listE[index].GetFunction(), listE[index + 1].GetNumber()); // Replacing the elements listE.Insert(index, n); listE.RemoveRange(index + 1, 2); } } } return listE; }
private object VisitExpr([NotNull] SqlParser.ExprContext context, bool considerColumnAlias) { if (context.K_IN() != null && (context.in_list_expr() != null || context.factored_select_stmt() != null)) { var result = new OperationExpression() { OperationType = OperationType.Binary, Operator = context.K_NOT() != null ? "NOT IN" : "IN", SubExpressions = new List <IExpression>() }; result.SubExpressions.Add((IExpression)VisitExpr(context.expr(0))); if (context.factored_select_stmt() != null) { var statement = (SelectStatement)VisitFactored_select_stmt(context.factored_select_stmt()); result.SubExpressions.Add(new SubQueryExpression() { Statement = statement }); } else { var listExpression = new ListExpression() { SubExpressions = new List <IExpression>() }; result.SubExpressions.Add(listExpression); foreach (var item in context.in_list_expr().expr()) { listExpression.SubExpressions.Add((IExpression)VisitExpr(item)); } } return(result); } if (context.K_EXISTS() != null && context.factored_select_stmt() != null) { var statement = (SelectStatement)VisitFactored_select_stmt(context.factored_select_stmt()); var result = new OperationExpression() { OperationType = OperationType.Unary, Operator = context.K_NOT() != null ? "NOT EXISTS" : "EXISTS", SubExpressions = new List <IExpression>() { new SubQueryExpression() { Statement = statement, } } }; return(result); } if (context.column_name() != null) { var table = context.table_name() == null ? "" : context.table_name().GetText(); var column = context.column_name().GetText(); var tableMap = queryTableStack.Peek(); var columMap = queryColumnStack.Peek(); if (considerColumnAlias && TryGetColumnExpressionByAlias(columMap, column, out var columnExpression)) { return(columnExpression); } GetTableNameAlias(tableMap, table, out var tableName, out var tableAlias); return(new ColumnExpression() { ColumnName = EscapeTableOrColumnName(column), TableName = tableName, TableAlias = tableAlias }); } if (context.function() != null) { var func = new FunctionExpression { FunctionName = context.function().function_name().GetText() }; if (!GCSqlVisitorCheck.FunctionsDict.TryGetValue(func.FunctionName, out var parametersInfo)) { throw new SQLParseException($"Not supported function '{func.FunctionName}'"); } // parameter count check var parameterCount = context.function().args_list()?.expr()?.Length ?? 0; if (parameterCount < parametersInfo.Min || parameterCount > parametersInfo.Max) { if (parametersInfo.Min == parametersInfo.Max) { throw new SQLParseException($"Not '{func.FunctionName}' function accpet {parametersInfo.Max} parameter(s)"); } else { throw new SQLParseException($"Not '{func.FunctionName}' function accpet {parametersInfo.Min} to {parametersInfo.Max} parameter(s)"); } } func.SubExpressions = new List <IExpression>(); if (context.function().args_list() != null) { if (context.function().args_list().GetText() == "*") { func.SubExpressions.Add(new KeywordExpression() { Keyword = context.function().args_list().GetText() }); } else { var exprList = context.function().args_list().expr(); if (exprList != null && exprList.Length != 0) { for (int i = 0; i < exprList.Length; i++) { var item = exprList[i]; IExpression argumentExpression = null; var descriptor = parametersInfo.Descriptors != null && i < parametersInfo.Descriptors.Length ? parametersInfo.Descriptors[i] : null; if (descriptor != null) { switch (descriptor.DescriptorType) { case ParameterDescriptorType.Enum: var parameterText = item?.GetText(); if (!descriptor.CheckParameter(parameterText)) { throw new SQLParseException($"'{parameterText}' is not a recognized datepart option."); } argumentExpression = new LiteralValueExpression() { Value = parameterText, ValueType = LiteralValueType.String, }; break; default: // do not need special handling. break; } } argumentExpression = argumentExpression ?? (IExpression)VisitExpr(item); func.SubExpressions.Add(argumentExpression); } } } } return(func); } if (context.unary_operator() != null) { var result = new OperationExpression() { OperationType = OperationType.Unary }; result.Operator = context.unary_operator().GetText().ToUpper(); result.SubExpressions = new List <IExpression> { (IExpression)VisitExpr((SqlParser.ExprContext)context.unary_operator().Parent.GetChild(1)) }; // special handling for the not exists, in order to reduce the layer of the expression if (result.SubExpressions.Count == 1 && (result.SubExpressions[0] as OperationExpression)?.Operator == "EXISTS") { ((OperationExpression)result.SubExpressions[0]).Operator = "NOT EXISTS"; return(result.SubExpressions[0]); } return(result); } if (context.BIND_PARAMETER() != null) { return(new ParamExpression() { ParamName = context.GetText() }); } if (context.ChildCount == 1) { if (context.literal_value() != null) { var value = context.literal_value(); var text = value.GetText(); if (!string.IsNullOrEmpty(text) && text.StartsWith("'") && text.EndsWith("'")) { text = text.Substring(1, text.Length - 2); } var result = new LiteralValueExpression() { Value = text }; if (value.NUMERIC_LITERAL() != null) { result.ValueType = LiteralValueType.Number; } else if (value.STRING_LITERAL() != null) { result.ValueType = LiteralValueType.String; } else if (value.NUMERIC_BOOLEAN() != null) { result.ValueType = LiteralValueType.Boolean; } else if (value.BLOB_LITERAL() != null) { result.ValueType = LiteralValueType.Blob; } else if (value.K_NULL() != null) { result.ValueType = LiteralValueType.Null; } return(result); } } else if (context.ChildCount == 2) { if (context.K_ISNULL() != null) { var result = new OperationExpression() { OperationType = OperationType.Binary, Operator = "IS" }; result.SubExpressions = new List <IExpression> { (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(0)), new LiteralValueExpression() { ValueType = LiteralValueType.Null, Value = "NULL" } }; return(result); } } else if (context.ChildCount == 3) { if (context.GetChild(0).GetText() == "(" && context.GetChild(2).GetText() == ")") { return(VisitExpr((SqlParser.ExprContext)context.GetChild(1))); } var result = new OperationExpression() { OperationType = OperationType.Binary }; var op = context.GetChild(1).GetText().ToUpper(); switch (op) { case "AND": case "OR": case "*": case "/": case "+": case "-": case "=": case "!=": case "<>": case ">": case "<": case ">=": case "<=": case "<<": case ">>": case "&": case "|": case "%": case "LIKE": { result.Operator = op; result.SubExpressions = new List <IExpression> { (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(0)), (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(2)) }; } break; case "IS": { result.SubExpressions = new List <IExpression>() { (IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(0)) }; if (context.GetChild(2) is SqlParser.ExprContext exprContext) { if (exprContext.ChildCount == 2 && exprContext.unary_operator() != null && exprContext.unary_operator().K_NOT() != null && exprContext.GetChild(1).GetText().ToUpper() == "NULL") { result.Operator = "IS NOT"; result.SubExpressions.Add(new LiteralValueExpression() { Value = "NULL", ValueType = LiteralValueType.Null }); } else { result.Operator = op; result.SubExpressions.Add((IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(2))); } } else { result.Operator = op; result.SubExpressions.Add((IExpression)VisitExpr((SqlParser.ExprContext)context.GetChild(2))); } } break; } return(result); } else if (context.ChildCount == 4) { if (context.expr().Length == 2 && context.GetChild(1).GetText().ToUpper() == "NOT" && context.GetChild(2).GetText().ToUpper() == "LIKE") { var result = new OperationExpression() { OperationType = OperationType.Binary, Operator = "NOT LIKE", SubExpressions = new List <IExpression>() { (IExpression)VisitExpr(context.expr(0)), (IExpression)VisitExpr(context.expr(1)) } }; return(result); } } else if (context.ChildCount == 5 && context.expr().Length == 3 && context.GetChild(1).GetText().ToUpper() == "BETWEEN" && context.GetChild(3).GetText().ToUpper() == "AND") { return(new BetweenExpression() { SubExpressions = new List <IExpression>() { (IExpression)VisitExpr(context.expr(0)), (IExpression)VisitExpr(context.expr(1)), (IExpression)VisitExpr(context.expr(2)) } }); } return(null); }
/// <summary> /// build an XPTreeNode for a select expression /// </summary> /// <param name="ctx"></param> /// <returns></returns> public bool BuildXPTNode(SelectExpressionContext ctx) { // literal if (ctx.literal() != null) { ctx.XPTreeNode = ctx.literal().XPTreeNode; return(true); } //| parameterName if (ctx.parameterName() != null) { ctx.XPTreeNode = ctx.parameterName().XPTreeNode; return(true); } //| variableName if (ctx.variableName() != null) { ctx.XPTreeNode = ctx.variableName().XPTreeNode; return(true); } if (ctx.selection() != null) { ctx.XPTreeNode = ctx.selection().XPTreeNode; return(true); } //| dataObjectEntryName if (ctx.dataObjectEntryName() != null) { ctx.XPTreeNode = ctx.dataObjectEntryName().XPTreeNode; return(true); } //| LPAREN selectExpression RPAREN if (ctx.LPAREN() != null && ctx.selectExpression().Count() == 1) { ctx.XPTreeNode = (IExpression)ctx.selectExpression()[0].XPTreeNode; // set the max priority for disabling reshuffle if (ctx.XPTreeNode != null && ctx.XPTreeNode is OperationExpression) { ((OperationExpression)ctx.XPTreeNode).Priority = uint.MaxValue; } return(true); } //| ( PLUS | MINUS ) selectExpression if (ctx.selectExpression().Count() == 1) { if (ctx.selectExpression()[0].XPTreeNode != null) { if (ctx.MINUS() != null) { ctx.XPTreeNode = new OperationExpression(new Token(Token.MINUS), new Literal(0), (IExpression)ctx.selectExpression()[0].XPTreeNode); } else { ctx.XPTreeNode = (IExpression)ctx.selectExpression()[0].XPTreeNode; } } else { return(false); } return(true); } //| logicalOperator_1 selectExpression if (ctx.logicalOperator_1() != null && ctx.selectExpression().Count() == 1) { if (ctx.selectExpression()[0].XPTreeNode != null) { ctx.XPTreeNode = new LogicalExpression(ctx.logicalOperator_1().Operator, (IExpression)ctx.selectExpression()[0].XPTreeNode); } else { return(false); } return(true); } //| selectExpression arithmeticOperator selectExpression if (ctx.arithmeticOperator().Count() > 0 && ctx.selectExpression().Count() > 1) { IExpression theExpression = (IExpression)ctx.selectExpression()[0].XPTreeNode; if (theExpression == null) { return(false); } for (uint i = 0; i < ctx.selectExpression().Count() - 1; i++) { Operator anOperator = ctx.arithmeticOperator()[i].Operator; if (!(theExpression is OperationExpression)) { if ((IExpression)ctx.selectExpression()[i + 1].XPTreeNode != null) { theExpression = new OperationExpression(anOperator, theExpression, (IExpression)ctx.selectExpression()[i + 1].XPTreeNode); } else { return(false); } } else { // x * y + z -> ( x * y) + z ) if (((OperationExpression)theExpression).Priority > anOperator.Priority) { if ((IExpression)ctx.selectExpression()[i + 1].XPTreeNode != null) { theExpression = new OperationExpression(anOperator, theExpression, (IExpression)ctx.selectExpression()[i + 1].XPTreeNode); } else { return(false); } } else { // x + y o* z -> x + ( y * z ) // build the new (lower) operation in the higher level tree (right with the last operand) IExpression right = (IExpression)((OperationExpression)theExpression).RightOperand; if (right != null && (IExpression)ctx.selectExpression()[i + 1].XPTreeNode != null) { ((OperationExpression)theExpression).RightOperand = new LogicalExpression(anOperator, right, (IExpression)ctx.selectExpression()[i + 1].XPTreeNode); } else { return(false); } } } } ctx.XPTreeNode = theExpression; return(true); } // return false return(false); }