internal void SetMinMaxFromSql(string value) { var tokens = new SqlTokenizer(value).ToArray(); var minText = default(SqlToken); var maxText = default(SqlToken); if (tokens.Length == 3) { if (!string.Equals(tokens[1].Text, "and", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException(); } minText = tokens[0]; maxText = tokens[2]; } else { var andToken = tokens.Single(t => string.Equals(t.Text, "and", StringComparison.OrdinalIgnoreCase)); minText = new SqlToken() { Text = "'" + value.Substring(0, andToken.StartOffset).Trim().Replace("'", "''") + "'", Type = SqlType.String }; maxText = new SqlToken() { Text = "'" + value.Substring(andToken.StartOffset + 3).Trim().Replace("'", "''") + "'", Type = SqlType.String }; } if (!Expressions.TryGetExpression(minText, out var min) || !Expressions.TryGetExpression(maxText, out var max)) { throw new InvalidOperationException(); } Min = min; Max = max; }
public static IExpression Parse(string whereClause, QueryItem table, IServerContext context = null) { context = context ?? ElementFactory.Utc.LocalizationContext; var tokens = new SqlTokenizer(whereClause).Where(t => t.Type != SqlType.Comment).ToArray(); var expressions = GetExpressions(tokens, table).ToArray(); var output = new List <IExpression>(); var ops = new List <IExpression>(); var last = default(IExpression); foreach (var expression in expressions) { var expr = expression; if (expr is ILiteral || expr is PropertyReference) { output.Push(expr); } else { if (expr is NotOperator && last is IsOperator) { expr = new NotIsOperator(); } else if (expr is AndOperator) { for (var i = ops.Count - 1; i >= 0; i--) { if (ops[i] is AndOperator) { break; } else if (ops[i] is BetweenOperator) { expr = new AndBetweenOperator(); break; } } } var precedence = GetPrecedence(expr); if (expr is EndParen) { while (ops.Count > 0 && !IsOpenParen(ops.Peek())) { output.Push(HandleOperator(ops.Pop(), output, context)); } var parenExpr = ops.Pop(); if (!IsOpenParen(last)) { var args = new List <IExpression>(); FlattenArgs(args, output.Pop()); if (ops.Count > 0 && ops.Peek() is InOperator && parenExpr is ListExpression listExpr) { foreach (var arg in args.Cast <IOperand>()) { listExpr.Values.Add(arg); } } else if (parenExpr is SqlFunction funcExpr) { foreach (var arg in args) { funcExpr.Add(arg); } parenExpr = funcExpr.Normalize(); } else if (args.Count == 1) { parenExpr = args[0]; } else { throw new NotSupportedException(); } } output.Push(parenExpr); } else if (expr is ListExpression && last is PropertyReference prop) { output.Pop(); ops.Push(new SqlFunction(prop.Name)); } else if (ops.Count < 1 || precedence > GetPrecedence(ops.Peek())) { ops.Push(expr); } else { while (ops.Count > 0 && precedence <= GetPrecedence(ops.Peek()) && !IsOpenParen(ops.Peek())) { output.Push(HandleOperator(ops.Pop(), output, context)); } ops.Push(expr); } } last = expr; } while (ops.Count > 0) { output.Push(HandleOperator(ops.Pop(), output, context)); } if (output.Count == 1) { return(output.Pop()); } throw new NotSupportedException(); }