Esempio n. 1
0
        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));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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;
        }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
        // 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);
            }
        }
Esempio n. 7
0
        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);
            }
        }
Esempio n. 8
0
        //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);
        }
Esempio n. 9
0
        /// <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;
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
        /// <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);
        }