public void Optimize_AdditionMultiplicationConstants()
        {
            // 1 + 2 * 3 => 7
            var ast = new SqlInfixOperationNode
            {
                Left     = new SqlNumberNode(1),
                Operator = new SqlOperatorNode("+"),
                Right    = new SqlInfixOperationNode
                {
                    Left     = new SqlNumberNode(2),
                    Operator = new SqlOperatorNode("*"),
                    Right    = new SqlNumberNode(3)
                }
            };

            var target = new ExpressionOptimizeVisitor();
            var result = target.Visit(ast);

            result.Should().MatchAst(new SqlNumberNode(7));
        }
Example #2
0
        private ISqlNode ParseBooleanExpression5(ITokenizer t)
        {
            // <BooleanExpression3> ("AND" | "OR") <BooleanExpression3>
            var left = ParseBooleanExpression4(t);

            while (t.Peek().IsKeyword("AND", "OR"))
            {
                var op    = new SqlOperatorNode(t.GetNext());
                var right = ParseBooleanExpression4(t);
                left = new SqlInfixOperationNode
                {
                    Location = op.Location,
                    Left     = left,
                    Operator = op,
                    Right    = right
                };
            }

            return(left);
        }
        private ISqlNode ParseScalarExpression3(ITokenizer t)
        {
            // Operators with + - precidence
            // <Expression2> (<op> <Expression2>)+
            var left = ParseScalarExpression2(t);

            while (t.Peek().IsSymbol("+", "-", "&", "^", "|"))
            {
                var op    = new SqlOperatorNode(t.GetNext());
                var right = ParseScalarExpression2(t);
                left = new SqlInfixOperationNode
                {
                    Location = op.Location,
                    Left     = left,
                    Operator = op,
                    Right    = right
                };
            }

            return(left);
        }
Example #4
0
        public ISqlNode VisitInfixOperation(SqlInfixOperationNode n)
        {
            void ToStringChild(ISqlNode node)
            {
                if (node is SqlInfixOperationNode)
                {
                    Append("(", node, ")");
                    return;
                }

                Visit(node);
            }

            if (n.IsUnionOperation())
            {
                Visit(n.Left);
                AppendLineAndIndent();
                Visit(n.Operator);
                AppendLineAndIndent();
                Visit(n.Right);
            }
            else if (n.IsBooleanOperation())
            {
                ToStringChild(n.Left);
                AppendLineAndIndent();
                Visit(n.Operator);
                Append(" ");
                ToStringChild(n.Right);
            }
            else
            {
                ToStringChild(n.Left);
                Append(" ");
                Visit(n.Operator);
                Append(" ");
                ToStringChild(n.Right);
            }

            return(n);
        }
        public override ISqlNode VisitInfixOperation(SqlInfixOperationNode n)
        {
            n = base.VisitInfixOperation(n) as SqlInfixOperationNode;
            if (n.IsArithmeticOperation())
            {
                if (n.Left is SqlNumberNode nl && n.Right is SqlNumberNode nr)
                {
                    var newNode = n.Operator.Apply(nl, nr);
                    newNode.Location = n.Location;
                    return(newNode);
                }

                if (n.Left is SqlStringNode sl && n.Right is SqlStringNode a)
                {
                    var newNode = n.Operator.Apply(sl, a);
                    newNode.Location = n.Location;
                    return(newNode);
                }
            }
            // TODO: If the operation is AND or OR and both sides can reduce to one of (TRUE, FALSE), we can reduce the whole thing

            return(n);
        }