示例#1
0
        private Expression BuildLinqExpression(ref ParserContext context, StatementPart part)
        {
            if (part.SubParts != null)
            {
                return(BuildLinqExpression(ref context, part.SubParts, part.SubParts.Count));
            }

            if (part.Variable != null)
            {
                var existing = context.LinqParameters.FirstOrDefault(x => x.Name == part.Variable);
                if (existing != null)
                {
                    return(existing);
                }

                var expression = Expression.Parameter(typeof(double), part.Variable);
                context.LinqParameters.Add(expression);
                return(expression);
            }
            else if (part.Number != null)
            {
                if (!Double.TryParse(part.Number, out double value))
                {
                    throw new MathParserException($"Invalid expression \"{part.Number}\" at \"{part.Index}\"");
                }
                var expression = Expression.Constant(value, typeof(double));
                return(expression);
            }
            else
            {
                throw new MathParserException($"Invalid expression \"{part.Token}\" at \"{part.Index}\"");
            }
        }
            // TODO: all operators
//            public CompareOperatorPart NotEqual() => BuildCompareOperatorPart(CompareOperatorKeyword.NotEqual);
//            public CompareOperatorPart GreaterThan() => BuildCompareOperatorPart(CompareOperatorKeyword.GreaterThan);
//            public CompareOperatorPart LessThan() => BuildCompareOperatorPart(CompareOperatorKeyword.LessThan);
//            public CompareOperatorPart GreaterThanOrEqual() => BuildCompareOperatorPart(CompareOperatorKeyword.GreaterThanOrEqual);
//            public CompareOperatorPart LessThanOrEqual() => BuildCompareOperatorPart(CompareOperatorKeyword.LessThanOrEqual);
//            public CompareOperatorPart StartsWith() => BuildCompareOperatorPart(CompareOperatorKeyword.StartsWith);
//            public CompareOperatorPart EndsWith() => BuildCompareOperatorPart(CompareOperatorKeyword.EndsWith);
//            public CompareOperatorPart Contains() => BuildCompareOperatorPart(CompareOperatorKeyword.Contains);

            private StatementPart Build(StatementKeyword statementKeyword)
            {
                var part = new StatementPart(statementKeyword, TestQueryBuilder);

                TestQueryBuilder._queryParts.Add(part);
                return(part);
            }
示例#3
0
        private StatementPart ParseParts(ref ParserContext context)
        {
            var subparts   = new List <StatementPart>();
            var startIndex = context.Index;

            while (context.Index < context.Chars.Length)
            {
                while (Char.IsWhiteSpace(context.Current) && context.Index < context.Chars.Length)
                {
                    context.Next();
                }
                var subpart = ParseOperators(ref context);
                if (subpart == null)
                {
                    break;
                }
                subparts.Add(subpart);
            }
            while (Char.IsWhiteSpace(context.Current) && context.Index < context.Chars.Length)
            {
                context.Next();
            }
            var part = new StatementPart(startIndex, subparts);

            return(part);
        }
 private void VisitDatePartField(StatementPart datePart)
 {
     if (datePart.PartType == StatementPartType.ConstantPart)
     {
         var constantPart = (ConstantPart)datePart;
         // HACK: Not 100% sure it will always be convertible to an int?
         var value = Convert.ToInt32(constantPart.Value).ToString("D2");
         this.VisitField(new ConstantPart(value));
     }
     else
     {
         this.VisitField(datePart);
     }
 }
示例#5
0
        public override void EnterPredicate([NotNull] TSqlParser.PredicateContext context)
        {
            base.EnterPredicate(context);

            string debug          = context.GetText();
            var    sourceInterval = context.SourceInterval;

            Console.WriteLine("EnterPredicate:");
            Console.WriteLine(debug);
            Console.WriteLine("---");


            var select = GetStatementAsSelect();
            var part   = new StatementPart();

            part.StatementTableName = select.Tables.FirstOrDefault();
            part.Text            = context.GetText();
            part.StatementOrigin = "EnterPredicate";

            int      a        = context.Start.StartIndex;
            int      b        = context.Stop.StopIndex;
            Interval interval = new Interval(a, b);

            _charStream = context.Start.InputStream;

            part.TextWithWhiteSpace = _charStream.GetText(interval);

            var parent = context.Parent.Parent;

            if (parent != null)
            {
                part.StatementParent = parent.GetText();
                var tokenInterval = parent.SourceInterval;
                part.StatementParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval);
            }

            var grandparent = context.Parent.Parent.Parent;

            if (grandparent != null)
            {
                part.StatementGrandParent = grandparent.GetText();
                var tokenInterval = grandparent.SourceInterval;
                part.StatementGrandParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval);
            }

            part.ParseStatementPart();
            select.Statements.Add(part);
        }
示例#6
0
 private StatementPart ParseNumbersAndVariables(ref ParserContext context)
 {
     if (numbersAndLetters.Contains(context.Current))
     {
         int startIndex = context.Index;
         while (context.Index < context.Chars.Length)
         {
             context.Next();
             if (!numbersAndLetters.Contains(context.Current))
             {
                 int length = context.Index - startIndex;
                 var token  = context.Chars.Slice(startIndex, length).ToString();
                 var part   = new StatementPart(startIndex, token);
                 return(part);
             }
         }
     }
     return(null);
 }
示例#7
0
    public override void EnterPredicate([NotNull] TSqlParser.PredicateContext context)
    {
        base.EnterPredicate(context);
        Console.WriteLine(context.GetText());

        var part = new StatementPart();

        part.StatementTableName = _dmlStatement.Tables.FirstOrDefault();
        part.Text            = context.GetText();
        part.StatementOrigin = "EnterPredicate";

        part.TextWithWhiteSpace = GetWhiteSpaceFormat(context);

        var parent = context.Parent.Parent;

        if (parent != null)
        {
            part.StatementParent = parent.GetText();
            var tokenInterval = parent.SourceInterval;
            part.StatementParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval);
        }

        var grandparent = context.Parent.Parent.Parent;

        if (grandparent != null)
        {
            part.StatementGrandParent = grandparent.GetText();
            var tokenInterval = grandparent.SourceInterval;
            part.StatementGrandParentWithWhiteSpace = GetWhitespaceStringFromTokenInterval(tokenInterval);
        }

        if (!part.ParseStatementPart())
        {
            _dmlStatement.IsValid = false;
        }

        _dmlStatement.WhereClause.Conditions.Add(part);
    }
示例#8
0
        protected virtual StatementPart VisitUnary(UnaryExpression unaryExpression)
        {
            switch (unaryExpression.NodeType)
            {
            case ExpressionType.Not:
                var o = Visit(unaryExpression.Operand);

                if (o is ParameterPart op && op.ParameterType == typeof(bool))
                {
                    Parameters[op.Text] = !(bool)Parameters[op.Text];
                    return(o);
                }

                if (o is ColumnAccessPart oc && oc.ColumnType == typeof(bool))
                {
                    o = new StatementPart($"{o.Text} = {AddParameter(true)}");
                }

                return(new StatementPart($"NOT ({o})"));

            case ExpressionType.Convert:
                if (unaryExpression.Method != null)
                {
                    var value = Expression.Lambda(unaryExpression).Compile().DynamicInvoke();
                    if (value != null)
                    {
                        return(AddParameter(value));
                    }

                    return(null);
                }

                break;
            }

            return(Visit(unaryExpression.Operand));
        }
示例#9
0
 public SearchStep(StatementPart part) : this()
 {
     _part = part;
 }
示例#10
0
        protected virtual StatementPart VisitBinary(BinaryExpression binaryExpression)
        {
            var left  = Visit(binaryExpression.Left);
            var right = Visit(binaryExpression.Right);

            var leftca  = left as ColumnAccessPart;
            var rightca = right as ColumnAccessPart;

            var leftp  = left as ParameterPart;
            var rightp = right as ParameterPart;

            if (leftp != null && rightp != null)
            {
                // if both sides are parameters, let's do the comparison here
                Parameters.Remove(leftp.Text);
                Parameters.Remove(rightp.Text);

                var result = Expression.Lambda(binaryExpression).Compile().DynamicInvoke();
                return(AddParameter(result));
            }

            var isIntegral = leftp != null && leftp.ParameterType != typeof(bool);

            if (!isIntegral && rightp != null && rightp.ParameterType != typeof(bool))
            {
                isIntegral = true;
            }

            var operand = DialectProvider.BindOperand(binaryExpression.NodeType, isIntegral);


            if (operand == "AND" || operand == "OR")
            {
                if (leftca?.ColumnType == typeof(bool))
                {
                    left = new StatementPart($"{leftca.Text} = {AddParameter(true)}");
                }

                if (rightca?.ColumnType == typeof(bool))
                {
                    right = new StatementPart($"{rightca.Text} = {AddParameter(true)}");
                }

                if (leftp?.ParameterType == typeof(bool) || rightp?.ParameterType == typeof(bool))
                {
                    var boolValue = (bool)(leftp != null ? Parameters[leftp.Text] : Parameters[rightp.Text]);
                    if (operand == "AND")
                    {
                        if (boolValue)
                        {
                            return(leftp != null ? left : right);
                        }

                        return(AddParameter(false));
                    }

                    if (operand == "OR")
                    {
                        if (boolValue)
                        {
                            return(AddParameter(true));
                        }

                        return(leftp != null ? left : right);
                    }
                }
            }
            else
            {
                if (leftca != null && leftca.ColumnType.IsEnum() && rightp != null)
                {
                    Parameters[rightp.Text] = Enum.ToObject(leftca.ColumnType, Parameters[rightp.Text]);
                }

                if (rightca != null && rightca.ColumnType.IsEnum() && leftp != null)
                {
                    Parameters[leftp.Text] = Enum.ToObject(rightca.ColumnType, Parameters[leftp.Text]);
                }
            }

            if (right == null || left == null)
            {
                operand = operand == "=" ? "IS" : "IS NOT";
            }

            switch (operand)
            {
            case "MOD":
            case "COALESCE":
                return(new StatementPart($"{operand}({left},{right})"));

            default:
                StringBuilder part = new StringBuilder("(");
                part.Append(left == null ? "NULL" : left.ToString());
                part.Append(" ");
                part.Append(operand);
                part.Append(" ");
                part.Append(right == null ? "NULL" : right.ToString());
                part.Append(")");

                return(new StatementPart(part.ToString()));
            }
        }
示例#11
0
        private StatementPart ParseOperators(ref ParserContext context)
        {
            int            startIndex  = context.Index;
            MethodOperator methodFound = null;
            UnaryOperator  unaryFound  = null;
            BinaryOperator binaryFound = null;

            while (context.Index < context.Chars.Length)
            {
                context.Next();

                int length = context.Index - startIndex;
                if (length > operatorStringsMaxLength)
                {
                    break;
                }
                var partTokens = context.Chars.Slice(startIndex, length);
                foreach (var methodOperator in methodOperators)
                {
                    if (partTokens.SequenceEqual(methodOperator.TokenWithOpener.AsSpan()))
                    {
                        methodFound = methodOperator;
                        break;
                    }
                }
                foreach (var unaryOperator in unaryOperators)
                {
                    if (partTokens.SequenceEqual(unaryOperator.Token.AsSpan()))
                    {
                        unaryFound = unaryOperator;
                        break;
                    }
                }
                foreach (var binaryOperator in binaryOperators)
                {
                    if (partTokens.SequenceEqual(binaryOperator.Token.AsSpan()))
                    {
                        binaryFound = binaryOperator;
                        break;
                    }
                }

                if (methodFound != null)
                {
                    break; //ending ( guarentees can't be longer
                }
            }
            if (methodFound != null)
            {
                var argumentParts = new List <StatementPart>();
                while (context.Index < context.Chars.Length)
                {
                    context.GroupStack.Push(MethodOperator.ArgumentOpener);
                    var argumentPart = ParseParts(ref context);
                    argumentParts.Add(argumentPart);

                    if (context.Current != MethodOperator.ArgumentSeperator)
                    {
                        break;
                    }

                    context.Next();
                }

                var part = new StatementPart(startIndex, methodFound, argumentParts);
                return(part);
            }
            if (unaryFound != null && binaryFound != null)
            {
                if (unaryFound.Token.Length < binaryFound.Token.Length)
                {
                    binaryFound = null;
                }
                else if (unaryFound.Token.Length > binaryFound.Token.Length)
                {
                    unaryFound = null;
                }

                if (unaryFound != null && binaryFound != null)
                {
                    context.Reset(startIndex + unaryFound.Token.Length); //possibly looked for a longer operator name
                    var part = new StatementPart(startIndex, unaryFound, binaryFound);
                    return(part);
                }
            }
            if (unaryFound != null)
            {
                context.Reset(startIndex + unaryFound.Token.Length); //possibly looked for a longer operator name
                var part = new StatementPart(startIndex, unaryFound);
                return(part);
            }
            if (binaryFound != null)
            {
                context.Reset(startIndex + binaryFound.Token.Length); //possibly looked for a longer operator name
                var part = new StatementPart(startIndex, binaryFound);
                return(part);
            }

            context.Reset(startIndex);
            return(ParseGroupOpen(ref context));
        }