public void SqlSubqueryScalarExpressionTest()
        {
            SqlLiteralScalarExpression five  = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(5));
            SqlLiteralScalarExpression three = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(3));

            // (SELECT VALUE 5 + 3)
            SqlSubqueryScalarExpression subqueryScalarExpression = SqlSubqueryScalarExpression.Create(
                SqlQuery.Create(
                    SqlSelectClause.Create(
                        SqlSelectValueSpec.Create(
                            SqlBinaryScalarExpression.Create(
                                SqlBinaryScalarOperatorKind.Add,
                                five,
                                three))),
                    fromClause: null,
                    whereClause: null,
                    groupByClause: null,
                    orderByClause: null,
                    offsetLimitClause: null));

            AssertEvaluation(CosmosNumber64.Create(5 + 3), subqueryScalarExpression);
        }
示例#2
0
        public override SqlObject VisitLogical_scalar_expression([NotNull] sqlParser.Logical_scalar_expressionContext context)
        {
            Contract.Requires(context != null);

            SqlObject sqlObject;

            if (context.binary_scalar_expression() != null)
            {
                sqlObject = this.Visit(context.binary_scalar_expression());
            }
            else if (context.in_scalar_expression() != null)
            {
                sqlObject = this.Visit(context.in_scalar_expression());
            }
            else if (context.like_scalar_expression() != null)
            {
                sqlObject = this.Visit(context.like_scalar_expression());
            }
            else
            {
                // logical_expression binary_operator logical_expression
                Contract.Requires(context.ChildCount == 3);

                SqlScalarExpression left = (SqlScalarExpression)this.Visit(context.logical_scalar_expression(0));

                if (!CstToAstVisitor.binaryOperatorKindLookup.TryGetValue(
                        context.children[1].GetText(),
                        out SqlBinaryScalarOperatorKind operatorKind))
                {
                    throw new ArgumentOutOfRangeException($"Unknown logical operator: {context.children[1].GetText()}.");
                }

                SqlScalarExpression right = (SqlScalarExpression)this.Visit(context.logical_scalar_expression(1));

                sqlObject = SqlBinaryScalarExpression.Create(operatorKind, left, right);
            }

            return(sqlObject);
        }
        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"));

            // 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);
        }
示例#4
0
        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:
            {
                SqlArrayCreateScalarExpression 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++)
                {
                    SqlScalarExpression item     = arrayExp.Items[i];
                    SqlScalarExpression replitem = Substitute(replacement, toReplace, item);
                    items[i] = replitem;
                }

                return(SqlArrayCreateScalarExpression.Create(items));
            }

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

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

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

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

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

            case SqlObjectKind.FunctionCallScalarExpression:
            {
                SqlFunctionCallScalarExpression 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++)
                {
                    SqlScalarExpression item     = funcExp.Arguments[i];
                    SqlScalarExpression 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:
            {
                SqlMemberIndexerScalarExpression memberExp = into as SqlMemberIndexerScalarExpression;
                if (memberExp == null)
                {
                    throw new DocumentQueryException("Expected a SqlMemberIndexerScalarExpression, got a " + into.GetType());
                }

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

            case SqlObjectKind.PropertyRefScalarExpression:
            {
                // This is the leaf of the recursion
                SqlPropertyRefScalarExpression 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
                {
                    SqlScalarExpression 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);
            }
        }
        public void SqlExistsScalarExpressionTest()
        {
            CosmosObject tag = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["name"] = CosmosString.Create("asdf")
            });

            CosmosObject tags = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["tags"] = CosmosArray.Create(new List <CosmosElement>()
                {
                    tag
                }),
                ["_rid"] = CosmosString.Create("AYIMAMmFOw8YAAAAAAAAAA==")
            });

            CosmosObject tagsWrapped = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["c"]    = tags,
                ["_rid"] = CosmosString.Create("AYIMAMmFOw8YAAAAAAAAAA==")
            });

            // EXISTS(SELECT VALUE t.name FROM t in c.tags where t.name = "asdf")
            SqlExistsScalarExpression existsScalarExpressionMatched = SqlExistsScalarExpression.Create(
                SqlQuery.Create(
                    SqlSelectClause.Create(
                        SqlSelectValueSpec.Create(
                            TestUtils.CreatePathExpression("t", "name"))),
                    SqlFromClause.Create(
                        SqlArrayIteratorCollectionExpression.Create(
                            SqlIdentifier.Create("t"),
                            SqlInputPathCollection.Create(
                                SqlIdentifier.Create("c"),
                                SqlStringPathExpression.Create(
                                    null,
                                    SqlStringLiteral.Create("tags"))))),
                    SqlWhereClause.Create(
                        SqlBinaryScalarExpression.Create(
                            SqlBinaryScalarOperatorKind.Equal,
                            TestUtils.CreatePathExpression("t", "name"),
                            SqlLiteralScalarExpression.Create(SqlStringLiteral.Create("asdf")))),
                    groupByClause: null,
                    orderByClause: null,
                    offsetLimitClause: null));

            AssertEvaluation(CosmosBoolean.Create(true), existsScalarExpressionMatched, tagsWrapped);

            SqlExistsScalarExpression existsScalarExpressionNotMatched = SqlExistsScalarExpression.Create(
                SqlQuery.Create(
                    SqlSelectClause.Create(
                        SqlSelectValueSpec.Create(
                            TestUtils.CreatePathExpression("t", "name"))),
                    SqlFromClause.Create(
                        SqlArrayIteratorCollectionExpression.Create(
                            SqlIdentifier.Create("t"),
                            SqlInputPathCollection.Create(
                                SqlIdentifier.Create("c"),
                                SqlStringPathExpression.Create(
                                    null,
                                    SqlStringLiteral.Create("tags"))))),
                    SqlWhereClause.Create(
                        SqlBinaryScalarExpression.Create(
                            SqlBinaryScalarOperatorKind.NotEqual,
                            TestUtils.CreatePathExpression("t", "name"),
                            SqlLiteralScalarExpression.Create(SqlStringLiteral.Create("asdf")))),
                    groupByClause: null,
                    orderByClause: null,
                    offsetLimitClause: null));

            AssertEvaluation(CosmosBoolean.Create(false), existsScalarExpressionNotMatched, tagsWrapped);
        }
        public void SqlBinaryScalarExpressionTest()
        {
            SqlLiteralScalarExpression five             = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(5));
            SqlLiteralScalarExpression three            = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(3));
            SqlLiteralScalarExpression hello            = SqlLiteralScalarExpression.Create(SqlStringLiteral.Create("Hello"));
            SqlLiteralScalarExpression world            = SqlLiteralScalarExpression.Create(SqlStringLiteral.Create("World"));
            SqlLiteralScalarExpression trueBoolean      = SqlLiteralScalarExpression.Create(SqlBooleanLiteral.True);
            SqlLiteralScalarExpression falseBoolean     = SqlLiteralScalarExpression.Create(SqlBooleanLiteral.False);
            SqlLiteralScalarExpression nullLiteral      = SqlLiteralScalarExpression.Create(SqlNullLiteral.Singleton);
            SqlLiteralScalarExpression undefinedLiteral = SqlLiteralScalarExpression.Create(SqlUndefinedLiteral.Create());

            SqlArrayCreateScalarExpression  arrayCreateScalarExpresion1  = SqlArrayCreateScalarExpression.Create();
            SqlArrayCreateScalarExpression  arrayCreateScalarExpresion2  = SqlArrayCreateScalarExpression.Create(five);
            SqlObjectCreateScalarExpression objectCreateScalarExpression = SqlObjectCreateScalarExpression.Create();

            SqlBinaryScalarExpression fivePlusThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Add, five, three);

            AssertEvaluation(CosmosNumber64.Create(3 + 5), fivePlusThree);

            SqlBinaryScalarExpression trueAndFalse = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.And, trueBoolean, falseBoolean);

            AssertEvaluation(CosmosBoolean.Create(true && false), trueAndFalse);

            SqlBinaryScalarExpression falseAndUndefined = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.And, falseBoolean, undefinedLiteral);

            AssertEvaluation(CosmosBoolean.Create(false), falseAndUndefined);

            SqlBinaryScalarExpression trueAndUndefined = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.And, trueBoolean, undefinedLiteral);

            AssertEvaluation(Undefined, trueAndUndefined);

            try
            {
                SqlBinaryScalarExpression threeBitwiseAndFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.BitwiseAnd, three, five);
                AssertEvaluation(CosmosNumber64.Create(1), threeBitwiseAndFive);
            }
            catch (Exception)
            {
            }

            try
            {
                SqlBinaryScalarExpression threeBitwiseOrFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.BitwiseOr, three, five);
                AssertEvaluation(CosmosNumber64.Create(7), threeBitwiseOrFive);
            }
            catch (Exception)
            {
            }

            try
            {
                SqlBinaryScalarExpression threeBitwiseXorFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.BitwiseXor, three, five);
                AssertEvaluation(CosmosNumber64.Create(7), threeBitwiseXorFive);
            }
            catch (Exception)
            {
            }

            SqlBinaryScalarExpression nullCoalesceFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Coalesce, nullLiteral, five);

            AssertEvaluation(CosmosNull.Create(), nullCoalesceFive);

            SqlBinaryScalarExpression fiveDivideFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Divide, five, five);

            AssertEvaluation(CosmosNumber64.Create(5 / 5), fiveDivideFive);

            SqlBinaryScalarExpression fiveEqualFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Equal, five, five);

            AssertEvaluation(CosmosBoolean.Create(5 == 5), fiveEqualFive);

            SqlBinaryScalarExpression threeEqualFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Equal, three, five);

            AssertEvaluation(CosmosBoolean.Create(3 == 5), threeEqualFive);

            AssertEvaluation(
                CosmosBoolean.Create(true),
                SqlBinaryScalarExpression.Create(
                    SqlBinaryScalarOperatorKind.Equal,
                    arrayCreateScalarExpresion1,
                    arrayCreateScalarExpresion1));

            AssertEvaluation(
                CosmosBoolean.Create(false),
                SqlBinaryScalarExpression.Create(
                    SqlBinaryScalarOperatorKind.Equal,
                    arrayCreateScalarExpresion1,
                    arrayCreateScalarExpresion2));

            AssertEvaluation(
                CosmosBoolean.Create(false),
                SqlBinaryScalarExpression.Create(
                    SqlBinaryScalarOperatorKind.Equal,
                    arrayCreateScalarExpresion1,
                    objectCreateScalarExpression));

            SqlBinaryScalarExpression threeGreaterThanFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.GreaterThan, three, five);

            AssertEvaluation(CosmosBoolean.Create(3 > 5), threeGreaterThanFive);

            SqlBinaryScalarExpression fiveGreaterThanThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.GreaterThan, five, three);

            AssertEvaluation(CosmosBoolean.Create(5 > 3), fiveGreaterThanThree);

            SqlBinaryScalarExpression threeGreaterThanOrEqualFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.GreaterThanOrEqual, three, five);

            AssertEvaluation(CosmosBoolean.Create(3 >= 5), threeGreaterThanOrEqualFive);

            SqlBinaryScalarExpression fiveGreaterThanOrEqualThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.GreaterThanOrEqual, five, three);

            AssertEvaluation(CosmosBoolean.Create(5 >= 3), fiveGreaterThanOrEqualThree);

            SqlBinaryScalarExpression threeLessThanFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.LessThan, three, five);

            AssertEvaluation(CosmosBoolean.Create(3 < 5), threeLessThanFive);

            SqlBinaryScalarExpression fiveLessThanThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.LessThan, five, three);

            AssertEvaluation(CosmosBoolean.Create(5 < 3), fiveLessThanThree);

            SqlBinaryScalarExpression threeLessThanOrEqualFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.LessThanOrEqual, three, five);

            AssertEvaluation(CosmosBoolean.Create(3 <= 5), threeLessThanOrEqualFive);

            SqlBinaryScalarExpression fiveLessThanOrEqualThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.LessThanOrEqual, five, three);

            AssertEvaluation(CosmosBoolean.Create(5 <= 3), fiveLessThanOrEqualThree);

            SqlBinaryScalarExpression fiveModThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Modulo, five, three);

            AssertEvaluation(CosmosNumber64.Create(5 % 3), fiveModThree);

            SqlBinaryScalarExpression fiveMultiplyThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Multiply, five, three);

            AssertEvaluation(CosmosNumber64.Create(5 * 3), fiveMultiplyThree);

            SqlBinaryScalarExpression fiveNotEqualThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.NotEqual, five, three);

            AssertEvaluation(CosmosBoolean.Create(5 != 3), fiveNotEqualThree);

            SqlBinaryScalarExpression fiveNotEqualFive = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.NotEqual, five, five);

            AssertEvaluation(CosmosBoolean.Create(5 != 5), fiveNotEqualFive);

            SqlBinaryScalarExpression trueOrFalse = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Or, trueBoolean, falseBoolean);

            AssertEvaluation(CosmosBoolean.Create(true || false), trueOrFalse);

            SqlBinaryScalarExpression trueOrUndefined = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Or, trueBoolean, undefinedLiteral);

            AssertEvaluation(CosmosBoolean.Create(true), trueOrUndefined);

            SqlBinaryScalarExpression falseOrUndefined = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Or, falseBoolean, undefinedLiteral);

            AssertEvaluation(Undefined, falseOrUndefined);

            SqlBinaryScalarExpression helloConcatWorld = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.StringConcat, hello, world);

            AssertEvaluation(CosmosString.Create("Hello" + "World"), helloConcatWorld);

            SqlBinaryScalarExpression fiveSubtract3 = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Subtract, five, three);

            AssertEvaluation(CosmosNumber64.Create(5 - 3), fiveSubtract3);
        }
示例#7
0
        public void SqlSelectListSpecTest()
        {
            CosmosObject john = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["name"] = CosmosString.Create("John"),
                ["age"]  = CosmosNumber64.Create(25)
            });

            CosmosObject johnWrapped = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["c"] = john
            });

            // { c.name, c.age }
            SqlScalarExpression cDotName = TestUtils.CreatePathExpression("c", "name");

            SqlScalarExpression cDotAge = TestUtils.CreatePathExpression("c", "age");

            SqlSelectListSpec listSpec = SqlSelectListSpec.Create(
                SqlSelectItem.Create(cDotName),
                SqlSelectItem.Create(cDotAge));

            AssertEvaluation(john, listSpec, johnWrapped);

            // { c.name AS nameAlias }
            CosmosObject johnAliased = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["nameAlias"] = CosmosString.Create("John"),
            });

            SqlSelectListSpec listSpecWithAlias = SqlSelectListSpec.Create(SqlSelectItem.Create(cDotName, SqlIdentifier.Create("nameAlias")));

            AssertEvaluation(johnAliased, listSpecWithAlias, johnWrapped);

            // { 3 + 5 }
            CosmosObject johnNonPropertyName = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["$1"] = CosmosNumber64.Create(8)
            });

            SqlLiteralScalarExpression five          = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(5));
            SqlLiteralScalarExpression three         = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(3));
            SqlBinaryScalarExpression  fivePlusThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Add, five, three);

            SqlSelectListSpec listSpecNonMember = SqlSelectListSpec.Create(SqlSelectItem.Create(fivePlusThree));

            AssertEvaluation(johnNonPropertyName, listSpecNonMember);

            // { 3 + 5 AS Five Plus Three }
            CosmosObject johnNonPropertyNameAliased = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["Five Plus Three"] = CosmosNumber64.Create(8)
            });
            SqlSelectListSpec listSpecNonMemberAliased = SqlSelectListSpec.Create(SqlSelectItem.Create(fivePlusThree, SqlIdentifier.Create("Five Plus Three")));

            AssertEvaluation(johnNonPropertyNameAliased, listSpecNonMemberAliased);

            // { c.blah[0] }
            CosmosObject numberIndex = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["blah"] = CosmosArray.Create(
                    new List <CosmosElement>()
                {
                    CosmosNumber64.Create(0),
                    CosmosNumber64.Create(1),
                    CosmosNumber64.Create(2)
                })
            });

            CosmosObject numberIndexWrapped = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["c"] = numberIndex
            });

            CosmosObject numberIndexEval = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["$1"] = CosmosNumber64.Create(0)
            });

            SqlScalarExpression cDotBlah0       = TestUtils.CreatePathExpression("c", "blah", 0);
            SqlSelectListSpec   numberIndexSpec = SqlSelectListSpec.Create(SqlSelectItem.Create(cDotBlah0));

            AssertEvaluation(numberIndexEval, numberIndexSpec, numberIndexWrapped);
        }
        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());
            }
        }