Exemplo n.º 1
0
 public abstract TOutput Visit(SqlBinaryScalarExpression sqlObject, TArg input);
Exemplo n.º 2
0
 public abstract TResult Visit(SqlBinaryScalarExpression sqlObject);
        public static SqlScalarExpression Substitute(SqlScalarExpression replacement, SqlIdentifier toReplace, SqlScalarExpression into)
        {
            if (into == null)
            {
                return(null);
            }

            if (replacement == null)
            {
                throw new ArgumentNullException("replacement");
            }

            switch (into.Kind)
            {
            case SqlObjectKind.ArrayCreateScalarExpression:
            {
                var arrayExp = into as SqlArrayCreateScalarExpression;
                if (arrayExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlArrayCreateScalarExpression, got a " + into.GetType());
                }

                SqlScalarExpression[] items = new SqlScalarExpression[arrayExp.Items.Count];
                for (int i = 0; i < items.Length; i++)
                {
                    var item     = arrayExp.Items[i];
                    var replitem = Substitute(replacement, toReplace, item);
                    items[i] = replitem;
                }

                return(SqlArrayCreateScalarExpression.Create(items));
            }

            case SqlObjectKind.BinaryScalarExpression:
            {
                var binaryExp = into as SqlBinaryScalarExpression;
                if (binaryExp == null)
                {
                    throw new DocumentQueryException("Expected a BinaryScalarExpression, got a " + into.GetType());
                }

                var replleft  = Substitute(replacement, toReplace, binaryExp.LeftExpression);
                var replright = Substitute(replacement, toReplace, binaryExp.RightExpression);
                return(SqlBinaryScalarExpression.Create(binaryExp.OperatorKind, replleft, replright));
            }

            case SqlObjectKind.UnaryScalarExpression:
            {
                var unaryExp = into as SqlUnaryScalarExpression;
                if (unaryExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlUnaryScalarExpression, got a " + into.GetType());
                }

                var repl = Substitute(replacement, toReplace, unaryExp.Expression);
                return(SqlUnaryScalarExpression.Create(unaryExp.OperatorKind, repl));
            }

            case SqlObjectKind.LiteralScalarExpression:
            {
                return(into);
            }

            case SqlObjectKind.FunctionCallScalarExpression:
            {
                var funcExp = into as SqlFunctionCallScalarExpression;
                if (funcExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlFunctionCallScalarExpression, got a " + into.GetType());
                }

                SqlScalarExpression[] items = new SqlScalarExpression[funcExp.Arguments.Count];
                for (int i = 0; i < items.Length; i++)
                {
                    var item     = funcExp.Arguments[i];
                    var replitem = Substitute(replacement, toReplace, item);
                    items[i] = replitem;
                }

                return(SqlFunctionCallScalarExpression.Create(funcExp.Name, funcExp.IsUdf, items));
            }

            case SqlObjectKind.ObjectCreateScalarExpression:
            {
                SqlObjectCreateScalarExpression objExp = into as SqlObjectCreateScalarExpression;
                if (objExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlObjectCreateScalarExpression, got a " + into.GetType());
                }

                return(SqlObjectCreateScalarExpression.Create(
                           objExp
                           .Properties
                           .Select(prop => SqlObjectProperty.Create(prop.Name, Substitute(replacement, toReplace, prop.Expression)))));
            }

            case SqlObjectKind.MemberIndexerScalarExpression:
            {
                var memberExp = into as SqlMemberIndexerScalarExpression;
                if (memberExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlMemberIndexerScalarExpression, got a " + into.GetType());
                }

                var replMember = Substitute(replacement, toReplace, memberExp.MemberExpression);
                var replIndex  = Substitute(replacement, toReplace, memberExp.IndexExpression);
                return(SqlMemberIndexerScalarExpression.Create(replMember, replIndex));
            }

            case SqlObjectKind.PropertyRefScalarExpression:
            {
                // This is the leaf of the recursion
                var propExp = into as SqlPropertyRefScalarExpression;
                if (propExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlPropertyRefScalarExpression, got a " + into.GetType());
                }

                if (propExp.MemberExpression == null)
                {
                    if (propExp.PropertyIdentifier.Value == toReplace.Value)
                    {
                        return(replacement);
                    }
                    else
                    {
                        return(propExp);
                    }
                }
                else
                {
                    var replMember = Substitute(replacement, toReplace, propExp.MemberExpression);
                    return(SqlPropertyRefScalarExpression.Create(replMember, propExp.PropertyIdentifier));
                }
            }

            case SqlObjectKind.ConditionalScalarExpression:
            {
                SqlConditionalScalarExpression conditionalExpression = (SqlConditionalScalarExpression)into;
                if (conditionalExpression == null)
                {
                    throw new ArgumentException();
                }

                SqlScalarExpression condition = Substitute(replacement, toReplace, conditionalExpression.ConditionExpression);
                SqlScalarExpression first     = Substitute(replacement, toReplace, conditionalExpression.FirstExpression);
                SqlScalarExpression second    = Substitute(replacement, toReplace, conditionalExpression.SecondExpression);

                return(SqlConditionalScalarExpression.Create(condition, first, second));
            }

            case SqlObjectKind.InScalarExpression:
            {
                SqlInScalarExpression inExpression = (SqlInScalarExpression)into;
                if (inExpression == null)
                {
                    throw new ArgumentException();
                }

                SqlScalarExpression expression = Substitute(replacement, toReplace, inExpression.Expression);

                SqlScalarExpression[] items = new SqlScalarExpression[inExpression.Items.Count];
                for (int i = 0; i < items.Length; i++)
                {
                    items[i] = Substitute(replacement, toReplace, inExpression.Items[i]);
                }

                return(SqlInScalarExpression.Create(expression, inExpression.Not, items));
            }

            default:
                throw new ArgumentOutOfRangeException("Unexpected Sql Scalar expression kind " + into.Kind);
            }
        }
Exemplo n.º 4
0
 public abstract void Visit(SqlBinaryScalarExpression sqlObject);
Exemplo n.º 5
0
 public abstract TResult Visit(SqlBinaryScalarExpression scalarExpression);
Exemplo n.º 6
0
        private void AddFieldFromBinaryExpression(SqlBinaryScalarExpression expression, string name, MemoryDbDataReader.ResultBatch batch, RawData rawData)
        {
            var select = new SelectDataFromBinaryScalarExpression(expression, rawData);

            AddFieldFromSelectData(name, batch, select);
        }
        public static SqlScalarExpression Substitute(SqlScalarExpression replacement, SqlIdentifier toReplace, SqlScalarExpression into)
        {
            if (into == null)
            {
                return(null);
            }

            if (replacement == null)
            {
                throw new ArgumentNullException("replacement");
            }

            switch (into)
            {
            case SqlArrayCreateScalarExpression arrayExp:
            {
                SqlScalarExpression[] items = new SqlScalarExpression[arrayExp.Items.Length];
                for (int i = 0; i < items.Length; i++)
                {
                    SqlScalarExpression item     = arrayExp.Items[i];
                    SqlScalarExpression replitem = Substitute(replacement, toReplace, item);
                    items[i] = replitem;
                }

                return(SqlArrayCreateScalarExpression.Create(items));
            }

            case SqlBinaryScalarExpression binaryExp:
            {
                SqlScalarExpression replleft  = Substitute(replacement, toReplace, binaryExp.LeftExpression);
                SqlScalarExpression replright = Substitute(replacement, toReplace, binaryExp.RightExpression);
                return(SqlBinaryScalarExpression.Create(binaryExp.OperatorKind, replleft, replright));
            }

            case SqlUnaryScalarExpression unaryExp:
            {
                SqlScalarExpression repl = Substitute(replacement, toReplace, unaryExp.Expression);
                return(SqlUnaryScalarExpression.Create(unaryExp.OperatorKind, repl));
            }

            case SqlLiteralScalarExpression literalScalarExpression:
            {
                return(into);
            }

            case SqlFunctionCallScalarExpression funcExp:
            {
                SqlScalarExpression[] items = new SqlScalarExpression[funcExp.Arguments.Length];
                for (int i = 0; i < items.Length; i++)
                {
                    SqlScalarExpression item     = funcExp.Arguments[i];
                    SqlScalarExpression replitem = Substitute(replacement, toReplace, item);
                    items[i] = replitem;
                }

                return(SqlFunctionCallScalarExpression.Create(funcExp.Name, funcExp.IsUdf, items));
            }

            case SqlObjectCreateScalarExpression objExp:
            {
                return(SqlObjectCreateScalarExpression.Create(
                           objExp
                           .Properties
                           .Select(prop => SqlObjectProperty.Create(prop.Name, Substitute(replacement, toReplace, prop.Value)))
                           .ToImmutableArray()));
            }

            case SqlMemberIndexerScalarExpression memberExp:
            {
                SqlScalarExpression replMember = Substitute(replacement, toReplace, memberExp.Member);
                SqlScalarExpression replIndex  = Substitute(replacement, toReplace, memberExp.Indexer);
                return(SqlMemberIndexerScalarExpression.Create(replMember, replIndex));
            }

            case SqlPropertyRefScalarExpression propExp:
            {
                // This is the leaf of the recursion
                if (propExp.Member == null)
                {
                    if (propExp.Identifier.Value == toReplace.Value)
                    {
                        return(replacement);
                    }
                    else
                    {
                        return(propExp);
                    }
                }
                else
                {
                    SqlScalarExpression replMember = Substitute(replacement, toReplace, propExp.Member);
                    return(SqlPropertyRefScalarExpression.Create(replMember, propExp.Identifier));
                }
            }

            case SqlConditionalScalarExpression conditionalExpression:
            {
                SqlScalarExpression condition = Substitute(replacement, toReplace, conditionalExpression.Condition);
                SqlScalarExpression first     = Substitute(replacement, toReplace, conditionalExpression.Consequent);
                SqlScalarExpression second    = Substitute(replacement, toReplace, conditionalExpression.Alternative);

                return(SqlConditionalScalarExpression.Create(condition, first, second));
            }

            case SqlInScalarExpression inExpression:
            {
                SqlScalarExpression expression = Substitute(replacement, toReplace, inExpression.Needle);

                SqlScalarExpression[] items = new SqlScalarExpression[inExpression.Haystack.Length];
                for (int i = 0; i < items.Length; i++)
                {
                    items[i] = Substitute(replacement, toReplace, inExpression.Haystack[i]);
                }

                return(SqlInScalarExpression.Create(expression, inExpression.Not, items));
            }

            default:
                throw new ArgumentOutOfRangeException("Unexpected Sql Scalar expression kind " + into.GetType());
            }
        }
        public void Binary()
        {
            // Positive
            List <SqlParserBaselineTestInput> inputs = new List <SqlParserBaselineTestInput>();

            foreach (SqlBinaryScalarOperatorKind binaryOperator in (SqlBinaryScalarOperatorKind[])Enum.GetValues(typeof(SqlBinaryScalarOperatorKind)))
            {
                inputs.Add(
                    CreateInput(
                        description: binaryOperator.ToString(),
                        scalarExpression: SqlBinaryScalarExpression.Create(
                            binaryOperator,
                            SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(42)),
                            SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(1337))).ToString()));
            }

            // Order of operations
            inputs.Add(CreateInput(
                           description: "Multiplication, division, and remainder -> left to right",
                           scalarExpression: "1 / 2 * 3 % 4"));
            inputs.Add(CreateInput(
                           description: "Addition and subtraction -> left to right",
                           scalarExpression: "1 + 2 - 3 + 4"));
            inputs.Add(CreateInput(
                           description: "Relational operators -> left to right",
                           scalarExpression: "1 < 2 <= 3 > 4 >= 5"));
            inputs.Add(CreateInput(
                           description: "Equality operators -> left to right",
                           scalarExpression: "1 = 2 != 3 = 4"));
            inputs.Add(CreateInput(
                           description: "Bitwise AND > Bitwise XOR (exclusive or) > Bitwise OR (inclusive or)",
                           scalarExpression: "1 | 2 & 3 ^ 4"));
            inputs.Add(CreateInput(
                           description: "Logical AND > Logical OR",
                           scalarExpression: "1 AND 2 OR 3 AND 4"));
            inputs.Add(CreateInput(
                           description: "Conditional-expression Right to left",
                           scalarExpression: "1 ? 2 : 3 + 4"));
            inputs.Add(CreateInput(
                           description: "Multiplicative > Additive",
                           scalarExpression: "1 + 2 * 3 - 4 / 5"));
            inputs.Add(CreateInput(
                           description: "Additive > Relational",
                           scalarExpression: "1 + 2 < 2 + 3 <= 10 - 4 > 5 >= 3"));
            inputs.Add(CreateInput(
                           description: "Relational > Equality",
                           scalarExpression: "1 > 2 = false AND 1 > 2 != true"));
            inputs.Add(CreateInput(
                           description: "Equality > Bitwise AND",
                           scalarExpression: "1 = 2 & 3 != 4"));
            inputs.Add(CreateInput(
                           description: "Bitwise AND > Bitwise Exclusive OR",
                           scalarExpression: "1 ^ 2 & 3 ^ 4"));
            inputs.Add(CreateInput(
                           description: "Bitwise Exclusive OR > Bitwise Inclusive OR",
                           scalarExpression: "1 | 2 ^ 3 | 4"));
            inputs.Add(CreateInput(
                           description: "Bitwise Inclusive OR > Logical AND",
                           scalarExpression: "1 AND 2 | 3 AND 4"));
            inputs.Add(CreateInput(
                           description: "Logical AND > Logical OR",
                           scalarExpression: "1 OR 2 AND 3 OR 4"));
            inputs.Add(CreateInput(
                           description: "Logical OR > String Concat",
                           scalarExpression: "1 || 2 OR 3 || 4"));

            // Binary with logical expressions
            inputs.Add(CreateInput(
                           description: "AND with LIKE expressions",
                           scalarExpression: "r.name LIKE 12  AND r.name LIKE 34"));
            inputs.Add(CreateInput(
                           description: "OR with LIKE expression",
                           scalarExpression: "r.name LIKE 12  OR r.name LIKE 34"));
            inputs.Add(CreateInput(
                           description: "AND with IN expression",
                           scalarExpression: "r.name IN (1,2,3)  AND r.name IN (4,5,6)"));
            inputs.Add(CreateInput(
                           description: "OR with IN expression",
                           scalarExpression: "r.name IN (1,2,3)  OR r.name IN (4,5,6)"));
            inputs.Add(CreateInput(
                           description: "Double AND",
                           scalarExpression: "r.age = 1 AND r.age = 2 AND r.age = 3"));
            inputs.Add(CreateInput(
                           description: "Double OR",
                           scalarExpression: "r.age = 1 OR r.age = 2 OR r.age = 3"));
            inputs.Add(CreateInput(
                           description: "AND and then OR",
                           scalarExpression: "r.age = 1 AND r.age = 2 OR r.age = 3"));
            inputs.Add(CreateInput(
                           description: "OR and then AND",
                           scalarExpression: "r.age = 1 OR r.age = 2 AND r.age = 3"));

            // Negative
            inputs.Add(CreateInput(description: "Missing Right", scalarExpression: "42 +"));
            inputs.Add(CreateInput(description: "Missing Left", scalarExpression: "AND 1337"));
            inputs.Add(CreateInput(description: "Unknown Operator", scalarExpression: "42 # 1337"));

            this.ExecuteTestSuite(inputs);
        }
Exemplo n.º 9
0
 public override bool Visit(SqlBinaryScalarExpression sqlBinaryScalarExpression)
 {
     return(sqlBinaryScalarExpression.LeftExpression.Accept(this) ||
            sqlBinaryScalarExpression.RightExpression.Accept(this));
 }
Exemplo n.º 10
0
 public abstract void Visit(SqlBinaryScalarExpression scalarExpression);
 public override void Visit(SqlBinaryScalarExpression codeObject)
 {
     Format(codeObject);
 }
        public override CosmosElement Visit(
            SqlBinaryScalarExpression scalarExpression,
            CosmosElement document)
        {
            CosmosElement left  = scalarExpression.LeftExpression.Accept(this, document);
            CosmosElement right = scalarExpression.RightExpression.Accept(this, document);

            CosmosElement result;

            switch (scalarExpression.OperatorKind)
            {
            case SqlBinaryScalarOperatorKind.Add:
                result = PerformBinaryNumberOperation((number1, number2) => number1 + number2, left, right);
                break;

            case SqlBinaryScalarOperatorKind.And:
                result = PerformLogicalAnd(left, right);
                break;

            case SqlBinaryScalarOperatorKind.BitwiseAnd:
                result = PerformBinaryNumberOperation((number1, number2) => DoubleToInt32Bitwise(number1) & DoubleToInt32Bitwise(number2), left, right);
                break;

            case SqlBinaryScalarOperatorKind.BitwiseOr:
                result = PerformBinaryNumberOperation((number1, number2) => DoubleToInt32Bitwise(number1) | DoubleToInt32Bitwise(number2), left, right);
                break;

            case SqlBinaryScalarOperatorKind.BitwiseXor:
                result = PerformBinaryNumberOperation((number1, number2) => DoubleToInt32Bitwise(number1) ^ DoubleToInt32Bitwise(number2), left, right);
                break;

            case SqlBinaryScalarOperatorKind.Coalesce:
                if (left != Undefined)
                {
                    result = left;
                }
                else
                {
                    result = right;
                }

                break;

            case SqlBinaryScalarOperatorKind.Divide:
                result = PerformBinaryNumberOperation((number1, number2) => number1 / number2, left, right);
                break;

            case SqlBinaryScalarOperatorKind.Equal:
                result = PerformBinaryEquality(equals => equals, left, right);
                break;

            case SqlBinaryScalarOperatorKind.GreaterThan:
                result = PerformBinaryInequality((comparison) => comparison > 0, left, right);
                break;

            case SqlBinaryScalarOperatorKind.GreaterThanOrEqual:
                result = PerformBinaryInequality((comparison) => comparison >= 0, left, right);
                break;

            case SqlBinaryScalarOperatorKind.LessThan:
                result = PerformBinaryInequality((comparison) => comparison < 0, left, right);
                break;

            case SqlBinaryScalarOperatorKind.LessThanOrEqual:
                result = PerformBinaryInequality((comparison) => comparison <= 0, left, right);
                break;

            case SqlBinaryScalarOperatorKind.Modulo:
                result = PerformBinaryNumberOperation((number1, number2) => number1 % number2, left, right);
                break;

            case SqlBinaryScalarOperatorKind.Multiply:
                result = PerformBinaryNumberOperation((number1, number2) => number1 * number2, left, right);
                break;

            case SqlBinaryScalarOperatorKind.NotEqual:
                result = PerformBinaryEquality(equals => !equals, left, right);
                break;

            case SqlBinaryScalarOperatorKind.Or:
                result = PerformLogicalOr(left, right);
                break;

            case SqlBinaryScalarOperatorKind.StringConcat:
                result = PerformBinaryStringOperation((string1, string2) => string1 + string2, left, right);
                break;

            case SqlBinaryScalarOperatorKind.Subtract:
                result = PerformBinaryNumberOperation((number1, number2) => number1 - number2, left, right);
                break;

            default:
                throw new ArgumentException($"Unknown {nameof(SqlBinaryScalarOperatorKind)}: {scalarExpression.OperatorKind}");
            }

            return(result);
        }