Ejemplo n.º 1
0
        public override SqlObject VisitInScalarExpression([NotNull] sqlParser.InScalarExpressionContext context)
        {
            Contract.Requires(context != null);
            // scalar_expression K_NOT? K_IN '(' scalar_expression_list ')'

            SqlScalarExpression needle = (SqlScalarExpression)this.Visit(context.scalar_expression());
            bool not = context.K_NOT() != null;
            List <SqlScalarExpression> searchList = new List <SqlScalarExpression>();

            foreach (sqlParser.Scalar_expressionContext scalarExpressionContext in context.scalar_expression_list().scalar_expression())
            {
                searchList.Add((SqlScalarExpression)this.Visit(scalarExpressionContext));
            }

            return(SqlInScalarExpression.Create(needle, not, searchList));
        }
Ejemplo n.º 2
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1 &&
                    methodCallExpression.Arguments[0].NodeType == ExpressionType.Constant &&
                    methodCallExpression.Arguments[0].Type == typeof(char[]))
                {
                    char[] argumentsExpressions = (char[])((ConstantExpression)methodCallExpression.Arguments[0]).Value;
                    if (argumentsExpressions.Length == 0)
                    {
                        SqlScalarExpression str = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                        return(SqlFunctionCallScalarExpression.CreateBuiltin("RTRIM", str));
                    }
                }

                return(null);
            }
Ejemplo n.º 3
0
        private DataTypeInfo GuessDataType(SqlScalarExpression expression, DataTypeInfo currentDataType,
                                           MemoryDatabase database)
        {
            if (expression is SqlUnaryScalarExpression unaryExpression)
            {
                expression = unaryExpression.Expression;
            }
            switch (expression)
            {
            case SqlBuiltinScalarFunctionCallExpression function:
            {
                currentDataType = GetTypeFromFunction(currentDataType, function, database);
                break;
            }

            case SqlBinaryScalarExpression binary:
            {
                var newDataTypeLeft  = GuessDataType(binary.Left, currentDataType, database);
                var newDataTypeRight = GuessDataType(binary.Right, currentDataType, database);
                currentDataType = UpdateDataType(binary, newDataTypeLeft, newDataTypeRight, currentDataType);
                break;
            }

            case SqlLiteralExpression literal:
            {
                var newDataType = new DataTypeInfo(literal);
                currentDataType = UpdateDataType(literal, newDataType, currentDataType);
                break;
            }

            case SqlColumnRefExpression columnRef:
            {
                var columnName = Helper.GetColumnName(columnRef);
                var column     = Helper.FindColumn(new TableAndColumn( ), columnName,
                                                   new Dictionary <string, Table>( )
                    {
                        [_Table.FullName] = _Table
                    });
                currentDataType = UpdateDataType(columnRef, column, currentDataType);
                break;
            }

            default:
                throw new NotImplementedException($"GuessDataType() does not support expressions of type { expression.GetType(  )}");
            }
            return(currentDataType);
        }
        public SelectDataFromCaseExpression(SqlSearchedCaseExpression caseExpression, RawData rawData)
        {
            _Expression = caseExpression;
            _RawData    = rawData;
            if (_Expression.ElseExpression != null)
            {
                _FullTypeInfo     = Helper.DetermineFullTypeInfo(_Expression.ElseExpression, rawData);
                _ScalarExpression = _Expression.ElseExpression;
            }

            if (_Expression.ElseExpression == null || _FullTypeInfo.DbDataType == null)
            {
                var whenExpression = _Expression.WhenClauses.First( );
                _FullTypeInfo     = Helper.DetermineFullTypeInfo(whenExpression.ThenExpression, rawData);
                _ScalarExpression = whenExpression.ThenExpression;
            }
        }
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    SqlScalarExpression haystack = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression needle   = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("CONTAINS", haystack, needle));
                }
                else if (methodCallExpression.Arguments.Count == 2)
                {
                    SqlScalarExpression haystack = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    SqlScalarExpression needle   = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[1], context);
                    return(SqlFunctionCallScalarExpression.CreateBuiltin("CONTAINS", haystack, needle));
                }

                return(null);
            }
Ejemplo n.º 6
0
        public SqlScalarExpression Visit(MethodCallExpression methodCallExpression, TranslationContext context)
        {
            SqlScalarExpression result = this.VisitExplicit(methodCallExpression, context);

            if (result != null)
            {
                return(result);
            }

            result = this.VisitImplicit(methodCallExpression, context);
            if (result != null)
            {
                return(result);
            }

            throw new DocumentQueryException(string.Format(CultureInfo.CurrentCulture, ClientResources.MethodNotSupported, methodCallExpression.Method.Name));
        }
Ejemplo n.º 7
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    SqlScalarExpression memberExpression = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression indexExpression  = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    var arguments = new SqlScalarExpression[] {
                        memberExpression,
                        indexExpression,
                        ExpressionToSql.VisitScalarExpression(Expression.Constant(1), context)
                    };

                    return(SqlFunctionCallScalarExpression.CreateBuiltin("SUBSTRING", arguments));
                }

                return(null);
            }
        public override SqlObject VisitSelect_item([NotNull] sqlParser.Select_itemContext context)
        {
            Contract.Requires(context != null);

            SqlScalarExpression sqlScalarExpression = (SqlScalarExpression)this.Visit(context.scalar_expression());
            SqlIdentifier       alias;

            if (context.IDENTIFIER() != null)
            {
                alias = SqlIdentifier.Create(context.IDENTIFIER().GetText());
            }
            else
            {
                alias = default;
            }

            return(SqlSelectItem.Create(sqlScalarExpression, alias));
        }
Ejemplo n.º 9
0
        public override SqlObject VisitBinaryScalarExpression([NotNull] sqlParser.BinaryScalarExpressionContext context)
        {
            Contract.Requires(context != null);
            // scalar_expression binary_operator scalar_expression
            Contract.Requires(context.ChildCount == 3);

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

            if (!CstToAstVisitor.binaryOperatorKindLookup.TryGetValue(
                    context.binary_operator().GetText(),
                    out SqlBinaryScalarOperatorKind operatorKind))
            {
                throw new ArgumentOutOfRangeException($"Unknown binary operator: {context.binary_operator().GetText()}.");
            }

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

            return(SqlBinaryScalarExpression.Create(operatorKind, left, right));
        }
            private SqlScalarExpression VisitIN(Expression expression, ConstantExpression constantExpressionList, TranslationContext context)
            {
                List <SqlScalarExpression> items = new List <SqlScalarExpression>();

                foreach (var item in ((IEnumerable)(constantExpressionList.Value)))
                {
                    items.Add(ExpressionToSql.VisitConstant(Expression.Constant(item)));
                }

                // if the items list empty, then just return false expression
                if (items.Count == 0)
                {
                    return(new SqlLiteralScalarExpression(new SqlBooleanLiteral(false)));
                }

                SqlScalarExpression scalarExpression = ExpressionToSql.VisitScalarExpression(expression, context);

                return(new SqlInScalarExpression(scalarExpression, items.ToArray(), false));
            }
Ejemplo n.º 11
0
        public void SqlSelectValueSpecTest()
        {
            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
            });

            SqlScalarExpression cDotName = TestUtils.CreatePathExpression("c", "name");

            SqlSelectValueSpec valueSpec = SqlSelectValueSpec.Create(cDotName);

            AssertEvaluation(CosmosString.Create("John"), valueSpec, johnWrapped);
        }
            private SqlScalarExpression VisitIN(Expression expression, ConstantExpression constantExpressionList, TranslationContext context)
            {
                List <SqlScalarExpression> items = new List <SqlScalarExpression>();

                foreach (object item in (IEnumerable)constantExpressionList.Value)
                {
                    items.Add(ExpressionToSql.VisitConstant(Expression.Constant(item), context));
                }

                // if the items list empty, then just return false expression
                if (items.Count == 0)
                {
                    return(SqlLiteralScalarExpression.SqlFalseLiteralScalarExpression);
                }

                SqlScalarExpression scalarExpression = ExpressionToSql.VisitNonSubqueryScalarExpression(expression, context);

                return(SqlInScalarExpression.Create(scalarExpression, false, items.ToImmutableArray()));
            }
Ejemplo n.º 13
0
        private static SqlWhereClause CombineWithConjunction(SqlWhereClause first, SqlWhereClause second)
        {
            if (first == null)
            {
                return(second);
            }

            if (second == null)
            {
                return(first);
            }

            SqlScalarExpression       previousFilter = first.FilterExpression;
            SqlScalarExpression       currentFilter  = second.FilterExpression;
            SqlBinaryScalarExpression and            = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.And, previousFilter, currentFilter);
            SqlWhereClause            result         = SqlWhereClause.Create(and);

            return(result);
        }
Ejemplo n.º 14
0
        public override SqlObject VisitUnaryScalarExpression([NotNull] sqlParser.UnaryScalarExpressionContext context)
        {
            Contract.Requires(context != null);
            // unary_operator scalar_expression
            Contract.Requires(context.ChildCount == 2);

            string unaryOperatorText = context.unary_operator().GetText();

            if (!CstToAstVisitor.unaryOperatorKindLookup.TryGetValue(
                    unaryOperatorText,
                    out SqlUnaryScalarOperatorKind unaryOperator))
            {
                throw new ArgumentOutOfRangeException($"Unknown unary operator: {unaryOperatorText}.");
            }

            SqlScalarExpression expression = (SqlScalarExpression)this.Visit(context.scalar_expression());

            return(SqlUnaryScalarExpression.Create(unaryOperator, expression));
        }
Ejemplo n.º 15
0
        private static SqlScalarExpression GenerateMemberIndexerScalarExpressionFromPath(Path path)
        {
            if (path.Length < 1)
            {
                throw new ArgumentException($"{nameof(path)} is too short.");
            }

            if (!(path.First() is StringPathToken rootToken))
            {
                throw new ArgumentException($"{nameof(path)} did not start with a string.");
            }

            SqlScalarExpression rootExpression = SqlPropertyRefScalarExpression.Create(
                member: null,
                identifier: SqlIdentifier.Create(rootToken.PropertyName));

            foreach (PathToken token in path.Skip(1))
            {
                SqlLiteralScalarExpression memberIndexer;
                switch (token)
                {
                case StringPathToken stringPathToken:
                    memberIndexer = SqlLiteralScalarExpression.Create(
                        SqlStringLiteral.Create(
                            stringPathToken.PropertyName));
                    break;

                case IntegerPathToken integerPathToken:
                    memberIndexer = SqlLiteralScalarExpression.Create(
                        SqlNumberLiteral.Create(
                            integerPathToken.Index));
                    break;

                default:
                    throw new ArgumentException($"Unknown token type: {token.GetType()}; {token}");
                }

                rootExpression = SqlMemberIndexerScalarExpression.Create(rootExpression, memberIndexer);
            }

            return(rootExpression);
        }
Ejemplo n.º 16
0
 public static MemoryDbParameter GetParameter(MemoryDbCommand command, SqlScalarExpression scalarExpression)
 {
     switch (scalarExpression)
     {
     case SqlScalarVariableRefExpression variableRef:
     {
         var parameterName = variableRef.VariableName.TrimStart(new [] { '@' });
         if (command.Parameters.Contains(parameterName))
         {
             return(( MemoryDbParameter )command.Parameters[parameterName]);
         }
         if (command.Variables.Contains(variableRef.VariableName))
         {
             return(( MemoryDbParameter )command.Variables[variableRef.VariableName]);
         }
         throw new SqlInvalidVariableException(variableRef.VariableName);
     }
     }
     throw new NotImplementedException();
 }
Ejemplo n.º 17
0
            protected override SqlScalarExpression VisitImplicit(MethodCallExpression methodCallExpression, TranslationContext context)
            {
                if (methodCallExpression.Arguments.Count == 1)
                {
                    SqlScalarExpression left  = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression right = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);

                    return(SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Equal, left, right));
                }

                if (methodCallExpression.Arguments.Count == 2)
                {
                    SqlScalarExpression left            = ExpressionToSql.VisitScalarExpression(methodCallExpression.Object, context);
                    SqlScalarExpression right           = ExpressionToSql.VisitScalarExpression(methodCallExpression.Arguments[0], context);
                    SqlScalarExpression caseInsensitive = SqlStringWithComparisonVisitor.GetCaseInsensitiveExpression(methodCallExpression.Arguments[1]);

                    return(SqlFunctionCallScalarExpression.CreateBuiltin("STRINGEQUALS", left, right, caseInsensitive));
                }

                return(null);
            }
        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);
        }
Ejemplo n.º 19
0
        private SqlSelectClause Substitute(SqlSelectClause inputSelectClause, SqlTopSpec topSpec, SqlIdentifier inputParam, SqlSelectClause selectClause)
        {
            SqlSelectSpec selectSpec = inputSelectClause.SelectSpec;

            if (selectClause == null)
            {
                return(selectSpec != null?SqlSelectClause.Create(selectSpec, topSpec, inputSelectClause.HasDistinct) : null);
            }

            if (selectSpec is SqlSelectStarSpec)
            {
                return(SqlSelectClause.Create(selectSpec, topSpec, inputSelectClause.HasDistinct));
            }

            SqlSelectValueSpec selValue = selectSpec as SqlSelectValueSpec;

            if (selValue != null)
            {
                SqlSelectSpec intoSpec = selectClause.SelectSpec;
                if (intoSpec is SqlSelectStarSpec)
                {
                    return(SqlSelectClause.Create(selectSpec, topSpec, selectClause.HasDistinct || inputSelectClause.HasDistinct));
                }

                SqlSelectValueSpec intoSelValue = intoSpec as SqlSelectValueSpec;
                if (intoSelValue != null)
                {
                    SqlScalarExpression replacement         = SqlExpressionManipulation.Substitute(selValue.Expression, inputParam, intoSelValue.Expression);
                    SqlSelectValueSpec  selValueReplacement = SqlSelectValueSpec.Create(replacement);
                    return(SqlSelectClause.Create(selValueReplacement, topSpec, selectClause.HasDistinct || inputSelectClause.HasDistinct));
                }

                throw new DocumentQueryException("Unexpected SQL select clause type: " + intoSpec.Kind);
            }

            throw new DocumentQueryException("Unexpected SQL select clause type: " + selectSpec.Kind);
        }
Ejemplo n.º 20
0
        public override SqlObject VisitObjectCreateScalarExpression([NotNull] sqlParser.ObjectCreateScalarExpressionContext context)
        {
            Contract.Requires(context != null);
            // '{' object_propertty_list? '}'

            List <SqlObjectProperty> properties = new List <SqlObjectProperty>();

            if (context.object_propertty_list() != null)
            {
                sqlParser.Object_propertyContext[] propertyContexts = context.object_propertty_list().object_property();
                foreach (sqlParser.Object_propertyContext objectPropertyContext in propertyContexts)
                {
                    string name = CstToAstVisitor.GetStringValueFromNode(objectPropertyContext.STRING_LITERAL());
                    SqlScalarExpression value = (SqlScalarExpression)this.Visit(objectPropertyContext.scalar_expression());

                    SqlObjectProperty property = SqlObjectProperty.Create(
                        SqlPropertyName.Create(name),
                        value);
                    properties.Add(property);
                }
            }

            return(SqlObjectCreateScalarExpression.Create(properties));
        }
 public override void Visit(SqlScalarExpression codeObject)
 {
     Format(codeObject);
 }
Ejemplo n.º 22
0
        private void InitializeField(MemoryDbDataReader.ResultBatch batch, RawData rawData, SqlScalarExpression scalarExpression, string name)
        {
            switch (scalarExpression)
            {
            case SqlGlobalScalarVariableRefExpression globalRef:
                AddFieldFromGlobalVariable(globalRef, name, batch, rawData);
                break;

            case SqlScalarVariableRefExpression variableRef:
                AddFieldFromVariable(variableRef, name, batch, rawData);
                break;

            case SqlScalarRefExpression scalarRef:
                AddFieldFromColumn(( SqlObjectIdentifier )scalarRef.MultipartIdentifier, name, batch, rawData);
                break;

            case SqlLiteralExpression literalExpression:
                AddFieldFromLiteral(literalExpression, name, batch, rawData);
                break;

            case SqlBuiltinScalarFunctionCallExpression functionCall:
                AddFieldForFunctionCall(functionCall, name, batch, rawData);
                break;

            case SqlNullScalarExpression nullScalarExpression:
                AddFieldForNullScalarExpression(nullScalarExpression, name, batch, rawData);
                break;

            case SqlSearchedCaseExpression caseExpression:
                AddFieldFromCaseExpression(caseExpression, name, batch, rawData);
                break;

            case SqlBinaryScalarExpression binaryExpression:
                AddFieldFromBinaryExpression(binaryExpression, name, batch, rawData);
                break;

            case SqlUnaryScalarExpression unaryScalarExpression:
                InitializeField(batch, rawData, unaryScalarExpression.Expression, name);
                break;

            default:
                throw new NotImplementedException(
                          $"Currently expression of type {scalarExpression.GetType( )} is not implemented");
            }
        }
        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());
            }
        }
Ejemplo n.º 24
0
        /// <summary>
        /// Flatten subqueries into a single query by substituting their expressions in the current query.
        /// </summary>
        /// <returns>A flattened query.</returns>
        private QueryUnderConstruction Flatten()
        {
            // SELECT fo(y) FROM y IN (SELECT fi(x) FROM x WHERE gi(x)) WHERE go(y)
            // is translated by substituting fi(x) for y in the outer query
            // producing
            // SELECT fo(fi(x)) FROM x WHERE gi(x) AND (go(fi(x))
            if (this.inputQuery == null)
            {
                // we are flat already
                if (this.selectClause == null)
                {
                    // If selectClause doesn't exists, use SELECT v0 where v0 is the input parameter, instead of SELECT *.
                    string parameterName = this.fromParameters.GetInputParameter().Name;
                    SqlScalarExpression parameterExpression = SqlPropertyRefScalarExpression.Create(null, SqlIdentifier.Create(parameterName));
                    this.selectClause = SqlSelectClause.Create(SqlSelectValueSpec.Create(parameterExpression));
                }
                else
                {
                    this.selectClause = SqlSelectClause.Create(this.selectClause.SelectSpec, this.topSpec, this.selectClause.HasDistinct);
                }

                return(this);
            }

            QueryUnderConstruction flatInput   = this.inputQuery.Flatten();
            SqlSelectClause        inputSelect = flatInput.selectClause;
            SqlWhereClause         inputwhere  = flatInput.whereClause;

            // Determine the paramName to be replaced in the current query
            // It should be the top input parameter name which is not binded in this collection.
            // That is because if it has been binded before, it has global scope and should not be replaced.
            string           paramName        = null;
            HashSet <string> inputQueryParams = new HashSet <string>();

            foreach (Binding binding in this.inputQuery.fromParameters.GetBindings())
            {
                inputQueryParams.Add(binding.Parameter.Name);
            }

            foreach (Binding binding in this.fromParameters.GetBindings())
            {
                if (binding.ParameterDefinition == null || inputQueryParams.Contains(binding.Parameter.Name))
                {
                    paramName = binding.Parameter.Name;
                }
            }

            SqlIdentifier         replacement     = SqlIdentifier.Create(paramName);
            SqlSelectClause       composedSelect  = Substitute(inputSelect, inputSelect.TopSpec ?? this.topSpec, replacement, this.selectClause);
            SqlWhereClause        composedWhere   = Substitute(inputSelect.SelectSpec, replacement, this.whereClause);
            SqlOrderbyClause      composedOrderBy = Substitute(inputSelect.SelectSpec, replacement, this.orderByClause);
            SqlWhereClause        and             = QueryUnderConstruction.CombineWithConjunction(inputwhere, composedWhere);
            FromParameterBindings fromParams      = QueryUnderConstruction.CombineInputParameters(flatInput.fromParameters, this.fromParameters);
            SqlOffsetSpec         offsetSpec;
            SqlLimitSpec          limitSpec;

            if (flatInput.offsetSpec != null)
            {
                offsetSpec = flatInput.offsetSpec;
                limitSpec  = flatInput.limitSpec;
            }
            else
            {
                offsetSpec = this.offsetSpec;
                limitSpec  = this.limitSpec;
            }
            QueryUnderConstruction result = new QueryUnderConstruction(this.aliasCreatorFunc)
            {
                selectClause   = composedSelect,
                whereClause    = and,
                inputQuery     = null,
                fromParameters = flatInput.fromParameters,
                orderByClause  = composedOrderBy ?? this.inputQuery.orderByClause,
                offsetSpec     = offsetSpec,
                limitSpec      = limitSpec,
                alias          = new Lazy <ParameterExpression>(() => this.Alias)
            };

            return(result);
        }
        /// <summary>
        /// Converts a JToken to a semantically equivalent SqlScalarExpression.
        /// </summary>
        /// <param name="token">The JToken to convert.</param>
        /// <returns>The semantically equivalent SqlScalarExpression.</returns>
        public static SqlScalarExpression Convert(JToken token)
        {
            if (token == null)
            {
                return(Undefined);
            }

            switch (token.Type)
            {
            case JTokenType.Array:
            {
                List <SqlScalarExpression> items = new List <SqlScalarExpression>();
                foreach (JToken element in token)
                {
                    items.Add(JTokenToSqlScalarExpression.Convert(element));
                }

                return(SqlArrayCreateScalarExpression.Create(items.ToArray()));
            }

            case JTokenType.Boolean:
            {
                SqlBooleanLiteral literal = SqlBooleanLiteral.Create(token.ToObject <bool>());
                return(SqlLiteralScalarExpression.Create(literal));
            }

            case JTokenType.Null:
            {
                SqlNullLiteral literal = SqlNullLiteral.Singleton;
                return(SqlLiteralScalarExpression.Create(literal));
            }

            case JTokenType.Integer:
            case JTokenType.Float:
            {
                SqlNumberLiteral literal = SqlNumberLiteral.Create(token.ToObject <double>());
                return(SqlLiteralScalarExpression.Create(literal));
            }

            case JTokenType.Object:
            {
                List <SqlObjectProperty> properties = new List <SqlObjectProperty>();

                foreach (JProperty prop in (JToken)token)
                {
                    SqlPropertyName     name       = SqlPropertyName.Create(prop.Name);
                    JToken              value      = prop.Value;
                    SqlScalarExpression expression = JTokenToSqlScalarExpression.Convert(value);
                    SqlObjectProperty   property   = SqlObjectProperty.Create(name, expression);
                    properties.Add(property);
                }

                return(SqlObjectCreateScalarExpression.Create(properties.ToArray()));
            }

            case JTokenType.String:
            {
                SqlStringLiteral literal = SqlStringLiteral.Create(token.ToObject <string>());
                return(SqlLiteralScalarExpression.Create(literal));
            }

            default:
                throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, "Unsupported JsonType {0}", token.Type));
            }
        }
Ejemplo n.º 26
0
 public override void Visit(SqlScalarExpression codeObject)
 {
     // SqlParser does not work with some functions
     // Must parse token list
     ParseTokens(codeObject);
 }
Ejemplo n.º 27
0
 private DataTypeInfo UpdateDataType(SqlScalarExpression argument, DataTypeInfo newDataType, DataTypeInfo currentDataType)
 {
     return(newDataType);
 }
Ejemplo n.º 28
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);
            }
        }
Ejemplo n.º 29
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 SelectDataFromVariables(SqlScalarExpression scalarExpression, MemoryDbCommand command)
 {
     Expression = scalarExpression;
     _Parameter = Helper.GetParameter(command, scalarExpression);
 }