protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (this.inProjector)
            {
                return(functionCallExpression);
            }

            if (functionCallExpression.Arguments.Count == 1 &&
                (functionCallExpression.Function == SqlFunction.IsNotNull || functionCallExpression.Function == SqlFunction.IsNull) &&
                (functionCallExpression.Arguments[0].NodeType == ExpressionType.MemberInit || functionCallExpression.Arguments[0].NodeType == (ExpressionType)SqlExpressionType.ObjectReference))
            {
                Expression retval = null;

                foreach (var value in GetPrimaryKeyElementalExpressions(functionCallExpression.Arguments[0]))
                {
                    var current = new SqlFunctionCallExpression(functionCallExpression.Type, functionCallExpression.Function, value);

                    if (retval == null)
                    {
                        retval = current;
                    }
                    else
                    {
                        retval = Expression.And(retval, current);
                    }
                }

                return(retval);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionCallExpression)
        {
            var function  = functionCallExpression.Function;
            var arguments = functionCallExpression.Arguments;

            switch (function)
            {
            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("SYSDATETIME", false, arguments));

            case SqlFunction.ServerNow:
                return(new FunctionResolveResult("SYSUTCDATETIME", false, arguments));

            case SqlFunction.Substring:
                if (arguments.Count == 2)
                {
                    return(new FunctionResolveResult("SUBSTRING", false, arguments.Concat(Expression.Constant(Int32.MaxValue)).ToReadOnlyCollection()));
                }
                else
                {
                    return(new FunctionResolveResult("SUBSTRING", false, arguments));
                }

            case SqlFunction.StringLength:
                return(new FunctionResolveResult("LEN", false, arguments));
            }

            return(base.ResolveSqlFunction(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.Date:
                this.Write("CONVERT(date, ");
                this.Visit(functionCallExpression.Arguments[0]);
                this.Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddTimeSpan:
                this.Write("DATEADD(DAY, ");
                this.Write("CAST(");
                this.Visit(functionCallExpression.Arguments[1]);
                this.Write(" AS BIGINT)");
                this.Write(" / CAST(864000000000 AS BIGINT)");
                this.Write(", DATEADD(MS, ");
                this.Write("CAST(");
                this.Visit(functionCallExpression.Arguments[1]);
                this.Write(" AS BIGINT)");
                this.Write(" / CAST(10000 AS BIGINT) % 86400000, ");
                this.Visit(functionCallExpression.Arguments[0]);
                this.Write("))");
                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitSelect(SqlSelectExpression selectExpression)
        {
            if (selectExpression.Skip != null)
            {
                var rowNumber        = new SqlFunctionCallExpression(typeof(int), "ROW_NUMBER");
                var over             = new SqlOverExpression(rowNumber, selectExpression.OrderBy ?? new ReadOnlyList <Expression>(new [] { new SqlOrderByExpression(OrderType.Ascending, selectExpression.Columns[0].Expression) }));
                var additionalColumn = new SqlColumnDeclaration(RowColumnName, over);

                var newAlias     = selectExpression.Alias + "INNER";
                var innerColumns = new ReadOnlyList <SqlColumnDeclaration>(selectExpression.Columns.Select(c => c).Concat(new[] { additionalColumn }));

                var innerSelect = new SqlSelectExpression(selectExpression.Type, newAlias, innerColumns, selectExpression.From, selectExpression.Where, null, selectExpression.GroupBy, selectExpression.Distinct, null, null, selectExpression.ForUpdate);

                var outerColumns = selectExpression.Columns.Select(c => new SqlColumnDeclaration(c.Name, new SqlColumnExpression(c.Expression.Type, newAlias, c.Name)));

                Expression rowPredicate = Expression.GreaterThan(new SqlColumnExpression(typeof(int), newAlias, additionalColumn.Name), selectExpression.Skip);

                if (selectExpression.Take != null && !(selectExpression.Take is SqlTakeAllValueExpression))
                {
                    rowPredicate = Expression.And
                                   (
                        rowPredicate,
                        Expression.LessThanOrEqual(new SqlColumnExpression(typeof(int), newAlias, additionalColumn.Name), Expression.Add(selectExpression.Skip, selectExpression.Take))
                                   );
                }

                return(new SqlSelectExpression(selectExpression.Type, selectExpression.Alias, outerColumns, innerSelect, rowPredicate, null, selectExpression.ForUpdate));
            }

            return(base.VisitSelect(selectExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            foreach (var select in functionCallExpression.Arguments.OfType <SqlSelectExpression>())
            {
                MarkAllColumnsUsed(select.Alias, select.Columns.Select(c => c.Name));
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
Exemple #6
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Function == SqlFunction.Date)
            {
                return(Expression.Call(this.Visit(functionCallExpression.Arguments[0]), typeof(DateTime).GetProperty("Date").GetGetMethod(), null));
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionCallExpression)
        {
            var function  = functionCallExpression.Function;
            var arguments = functionCallExpression.Arguments;

            switch (function)
            {
            case SqlFunction.TrimLeft:
                return(new FunctionResolveResult("LTRIM", false, arguments));

            case SqlFunction.TrimRight:
                return(new FunctionResolveResult("RTRIM", false, arguments));

            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("UTC_TIMESTAMP", false, functionCallExpression.Arguments));

            case SqlFunction.TimeSpanFromSeconds:
                return(new FunctionResolveResult("", false, arguments)
                {
                    functionPrefix = "INTERVAL ",
                    functionSuffix = " SECOND",
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromMinutes:
                return(new FunctionResolveResult("", false, arguments[0])
                {
                    functionPrefix = "INTERVAL ",
                    functionSuffix = " MINUTE",
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromHours:
                return(new FunctionResolveResult("", false, arguments[0])
                {
                    functionPrefix = "INTERVAL ",
                    functionSuffix = " HOUR",
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromDays:
                return(new FunctionResolveResult("", false, arguments[0])
                {
                    functionPrefix = "INTERVAL ",
                    functionSuffix = " DAY",
                    excludeParenthesis = true
                });

            case SqlFunction.DateTimeAddTimeSpan:
                return(new FunctionResolveResult("DATE_ADD", false, arguments));
            }

            return(base.ResolveSqlFunction(functionCallExpression));
        }
Exemple #8
0
            public override SqlExpression VisitFunctionCall(SqlFunctionCallExpression expression)
            {
                var args = expression.Arguments;

                foreach (var arg in args)
                {
                    columnNames.AddRange(arg.DiscoverReferences());
                }

                return(base.VisitFunctionCall(expression));
            }
        protected virtual Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            var newArgs = this.VisitExpressionList(functionCallExpression.Arguments);

            if (newArgs != functionCallExpression.Arguments)
            {
                return(new SqlFunctionCallExpression(functionCallExpression.Type, functionCallExpression.Function, newArgs.ToArray()));
            }

            return(functionCallExpression);
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Function >= SqlFunction.NumberBasedDatePartStart &&
                functionCallExpression.Function <= SqlFunction.NumberBasedDatePartEnd)
            {
                this.Write("(CAST (");
                base.VisitFunctionCall(functionCallExpression);
                this.Write(" AS INTEGER))");

                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.DayOfWeek:
                this.Write("((");
                base.VisitFunctionCall(functionCallExpression);
                this.Write(") - 1)");

                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
Exemple #12
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Function == SqlFunction.Date)
            {
                return(Expression.Call(this.Visit(functionCallExpression.Arguments[0]), typeof(DateTime).GetProperty("Date").GetGetMethod(), null));
            }

            if (functionCallExpression.Function == SqlFunction.RecordsAffected)
            {
                return(Expression.Property(this.dataReader, TypeUtils.GetProperty <IDataReader>(c => c.RecordsAffected)));
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitSelect(SqlSelectExpression selectExpression)
        {
            if (selectExpression.Skip != null)
            {
                var rowNumber = new SqlFunctionCallExpression(typeof(int), "ROW_NUMBER");

                var oldAliases = (selectExpression.From as ISqlExposesAliases)?.Aliases;
                var innerSelectWithRowAlias = selectExpression.Alias + "_ROW";

                var cols = selectExpression.Columns.Select(c => new SqlColumnDeclaration(c.Name, new SqlColumnExpression(c.Expression.Type, selectExpression.Alias, c.Name))).ToList();
                var over = new SqlOverExpression(rowNumber, selectExpression.OrderBy?.Cast <SqlOrderByExpression>().ToReadOnlyCollection() ?? cols.Select(c => new SqlOrderByExpression(OrderType.Ascending, c.Expression)).ToReadOnlyCollection());

                if (oldAliases != null)
                {
                    over = (SqlOverExpression)AliasReferenceReplacer.Replace(over, oldAliases.Contains, selectExpression.Alias);
                }

                var rowColumn = new SqlColumnDeclaration(RowColumnName, over);

                cols.Add(rowColumn);

                var innerSelectWithRowColumns = cols.ToReadOnlyCollection();
                var innerSelectWithRow        = new SqlSelectExpression(selectExpression.Type, innerSelectWithRowAlias, innerSelectWithRowColumns, selectExpression.ChangeOrderBy(null).ChangeSkipTake(null, null), null, null, null, false, null, null, false);
                var outerColumns = selectExpression.Columns.Select(c => new SqlColumnDeclaration(c.Name, new SqlColumnExpression(c.Expression.Type, innerSelectWithRowAlias, c.Name)));

                Expression rowPredicate = Expression.GreaterThan(new SqlColumnExpression(typeof(int), innerSelectWithRowAlias, rowColumn.Name), selectExpression.Skip);

                if (selectExpression.Take != null && !(selectExpression.Take is SqlTakeAllValueExpression))
                {
                    rowPredicate = Expression.And
                                   (
                        rowPredicate,
                        Expression.LessThanOrEqual(new SqlColumnExpression(typeof(int), innerSelectWithRowAlias, rowColumn.Name), Expression.Add(selectExpression.Skip, selectExpression.Take))
                                   );
                }

                var newOrderBy = selectExpression
                                 .OrderBy?
                                 .Select(c => oldAliases == null ? c : AliasReferenceReplacer.Replace(c, oldAliases.Contains, innerSelectWithRowAlias))
                                 .Concat(new SqlOrderByExpression(OrderType.Ascending, new SqlColumnExpression(typeof(int), innerSelectWithRowAlias, rowColumn.Name)))
                                 .ToReadOnlyCollection();

                var retval = new SqlSelectExpression(selectExpression.Type, selectExpression.Alias, outerColumns, innerSelectWithRow, rowPredicate, newOrderBy, selectExpression.ForUpdate);

                return(retval);
            }

            return(base.VisitSelect(selectExpression));
        }
Exemple #14
0
        protected override FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionCallExpression)
        {
            var function  = functionCallExpression.Function;
            var arguments = functionCallExpression.Arguments;

            switch (function)
            {
            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("SYSDATETIME", false, arguments));

            case SqlFunction.ServerNow:
                return(new FunctionResolveResult("SYSUTCDATETIME", false, arguments));
            }

            return(base.ResolveSqlFunction(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Arguments.Count == 1 &&
                (functionCallExpression.Function == SqlFunction.IsNotNull || functionCallExpression.Function == SqlFunction.IsNull))
            {
                var arg0 = functionCallExpression.Arguments[0].StripAddToCollectionCalls();

                if ((arg0.NodeType == ExpressionType.MemberInit || arg0.NodeType == (ExpressionType)SqlExpressionType.ObjectReference))
                {
                    // Convert ObjectReference1 == ObjectReference2 -> ObjectReference1.PrimaryKey == ObjectReference2.PrimaryKey

                    Expression retval = null;

                    foreach (var value in GetPrimaryKeyElementalExpressions(arg0))
                    {
                        var current = new SqlFunctionCallExpression(functionCallExpression.Type, functionCallExpression.Function, value);

                        if (retval == null)
                        {
                            retval = current;
                        }
                        else
                        {
                            retval = Expression.And(retval, current);
                        }
                    }

                    return(retval);
                }
                else if ((SqlExpressionType)arg0.NodeType == SqlExpressionType.Projection)
                {
                    // Convert (SELECT a, b, c FROM T) == NULL -> NOT EXISTS (SELECT a, b, c FROM T)

                    Expression retval = new SqlFunctionCallExpression(typeof(bool), SqlFunction.Exists, Visit(arg0));

                    if (functionCallExpression.Function == SqlFunction.IsNull)
                    {
                        retval = Expression.Not(retval);
                    }

                    return(retval);
                }
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.DayOfWeek:
                Write("((");
                base.VisitFunctionCall(functionCallExpression);
                Write(") - 1)");

                return(functionCallExpression);

            case SqlFunction.DateTimeAddDays:
                Write("(");
                Write("DATE_ADD(");
                Visit(functionCallExpression.Arguments[0]);
                Write(", INTERVAL ");
                Visit(functionCallExpression.Arguments[1]);
                Write(" DAY))");

                return(functionCallExpression);

            case SqlFunction.DateTimeAddMonths:
                Write("(");
                Write("DATE_ADD(");
                Visit(functionCallExpression.Arguments[0]);
                Write(", INTERVAL ");
                Visit(functionCallExpression.Arguments[1]);
                Write(" MONTH))");

                return(functionCallExpression);

            case SqlFunction.DateTimeAddYears:
                Write("(");
                Write("DATE_ADD(");
                Visit(functionCallExpression.Arguments[0]);
                Write(", INTERVAL ");
                Visit(functionCallExpression.Arguments[1]);
                Write(" YEAR))");

                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
Exemple #17
0
        protected override Expression VisitInsertInto(SqlInsertIntoExpression expression)
        {
            if (expression.ReturningAutoIncrementColumnNames != null && expression.ReturningAutoIncrementColumnNames.Count == 1)
            {
                var returningColumnName = expression.ReturningAutoIncrementColumnNames[0];
                var index = expression.ColumnNames.IndexOf(returningColumnName);

                if (index > 0)
                {
                    var newValueExpressions = new List <Expression>(expression.ValueExpressions);

                    newValueExpressions[index] = new SqlFunctionCallExpression(newValueExpressions[index].Type, "LAST_INSERT_ID", newValueExpressions[index]);

                    return(new SqlInsertIntoExpression(expression.Source, expression.ColumnNames, expression.ReturningAutoIncrementColumnNames, newValueExpressions));
                }
            }

            return(expression);
        }
Exemple #18
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.TimeSpanFromDays:
                return(Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(24 * 60 * 60.0 * 10000000.0), Expression.Convert(this.Visit(functionCallExpression.Arguments[0]), typeof(double))));

            case SqlFunction.TimeSpanFromHours:
                return(this.Visit(Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(60.0 * 60.0 * 10000000.0), Expression.Convert(this.Visit(functionCallExpression.Arguments[0]), typeof(double)))));

            case SqlFunction.TimeSpanFromMinutes:
                return(this.Visit(Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(60.0 * 10000000.0), Expression.Convert(this.Visit(functionCallExpression.Arguments[0]), typeof(double)))));

            case SqlFunction.TimeSpanFromSeconds:
                return(this.Visit(Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(10000000.0), Expression.Convert(this.Visit(functionCallExpression.Arguments[0]), typeof(double)))));
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.DateTimeAddDays:
                this.Write("(");
                this.Visit(functionCallExpression.Arguments[0]);
                this.Write(" + (");
                this.Visit(functionCallExpression.Arguments[1]);
                this.Write(" || ");
                this.Visit(Expression.Constant(" day"));
                this.Write(")");
                this.Write("::interval");
                this.Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddMonths:
                this.Write("(");
                this.Visit(functionCallExpression.Arguments[0]);
                this.Write(" + (");
                this.Visit(functionCallExpression.Arguments[1]);
                this.Write(" || ");
                this.Visit(Expression.Constant(" month"));
                this.Write(")");
                this.Write("::interval");
                this.Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddYears:
                this.Write("(");
                this.Visit(functionCallExpression.Arguments[0]);
                this.Write(" + (");
                this.Visit(functionCallExpression.Arguments[1]);
                this.Write(" || ");
                this.Visit(Expression.Constant(" year"));
                this.Write(")");
                this.Write("::interval");
                this.Write(")");
                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.Year:
            case SqlFunction.Week:
            case SqlFunction.DayOfYear:
            case SqlFunction.DayOfMonth:
            case SqlFunction.DayOfWeek:
            case SqlFunction.Minute:
            case SqlFunction.Second:
            case SqlFunction.Hour:
                this.Write("(CAST (");
                base.VisitFunctionCall(functionCallExpression);
                this.Write(" AS INTEGER))");

                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
Exemple #21
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            this.output.Append(functionCallExpression.Function);
            this.output.Append("\"");

            foreach (var arg in functionCallExpression.Arguments)
            {
                this.Visit(arg);

                this.output.Append(", ");
            }

            if (functionCallExpression.Arguments.Count > 0)
            {
                this.output.Length -= 2;
            }

            this.output.Append("\"");

            return(functionCallExpression);
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Function == SqlFunction.In)
            {
                if (functionCallExpression.Arguments[0].NodeType == ExpressionType.Constant && functionCallExpression.Arguments[1].NodeType == (ExpressionType)SqlExpressionType.Projection)
                {
                    var projector = (SqlProjectionExpression)functionCallExpression.Arguments[1];

                    if (projector.Select.Where == null && projector.Select.Columns.Count == 1)
                    {
                        var newWhere      = Expression.Equal(functionCallExpression.Arguments[0], projector.Select.Columns[0].Expression);
                        var newSelect     = projector.Select.ChangeWhere(newWhere);
                        var newProjection = new SqlProjectionExpression(newSelect, projector, projector.Aggregator);

                        return(new SqlFunctionCallExpression(functionCallExpression.Type, SqlFunction.Exists, newProjection));
                    }
                }
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
Exemple #23
0
        protected override Expression VisitBinary(BinaryExpression binaryExpression)
        {
            if (binaryExpression.NodeType == ExpressionType.NotEqual ||
                binaryExpression.NodeType == ExpressionType.Equal)
            {
                var function = binaryExpression.NodeType == ExpressionType.NotEqual ? SqlFunction.IsNotNull : SqlFunction.IsNull;

                var functionCallExpression = binaryExpression.Left as SqlFunctionCallExpression;
                var otherExpression        = binaryExpression.Right;

                if (functionCallExpression == null)
                {
                    functionCallExpression = binaryExpression.Right as SqlFunctionCallExpression;
                    otherExpression        = binaryExpression.Left;
                }

                if (functionCallExpression != null && functionCallExpression.Function == SqlFunction.CollectionCount)
                {
                    var constantExpression = otherExpression as ConstantExpression;

                    if (constantExpression != null)
                    {
                        if (constantExpression.Type == typeof(int) || constantExpression.Type == typeof(long))
                        {
                            if (Convert.ToInt32(constantExpression.Value) == 0)
                            {
                                var isNull  = new SqlFunctionCallExpression(typeof(bool), SqlFunction.IsNull, functionCallExpression.Arguments[0]);
                                var isEmpty = Expression.Equal(functionCallExpression.Arguments[0], Expression.Constant(""));

                                return(Expression.Or(isNull, isEmpty));
                            }
                        }
                    }

                    throw new NotSupportedException("Blobbed list counts can only be compared to const 0");
                }
            }
            return(base.VisitBinary(binaryExpression));
        }
Exemple #24
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Arguments.Count == 2)
            {
                if (functionCallExpression.Function == SqlFunction.Concat)
                {
                    SqlFunctionCallExpression retval;

                    var arg1 = functionCallExpression.Arguments[0] as SqlFunctionCallExpression;
                    var arg2 = functionCallExpression.Arguments[1] as SqlFunctionCallExpression;

                    if (arg1 == null && arg2 != null && arg2.Function == SqlFunction.Concat)
                    {
                        // Concat(something, Concat(?, ?))

                        var arg1Args = Visit(functionCallExpression.Arguments[0]);
                        var arg2Args = new List <Expression>();

                        foreach (var arg in arg2.Arguments)
                        {
                            arg2Args.Add(Visit(arg));
                        }

                        retval = new SqlFunctionCallExpression(functionCallExpression.Type, SqlFunction.Concat, arg2Args.ToArray().Prepend(arg1Args));

                        return(retval);
                    }
                    else if (arg1 != null && arg2 == null && arg1.Function == SqlFunction.Concat)
                    {
                        // Concat(Concat(?, ?), something)

                        var arg2Args = Visit(functionCallExpression.Arguments[1]);
                        var arg1Args = new List <Expression>();

                        foreach (var arg in arg1.Arguments)
                        {
                            arg1Args.Add(Visit(arg));
                        }

                        retval = new SqlFunctionCallExpression(functionCallExpression.Type, SqlFunction.Concat, arg1Args.ToArray().Append(arg2Args));

                        return(retval);
                    }
                    else if (arg1 != null && arg2 != null && arg1.Function == SqlFunction.Concat && arg2.Function == SqlFunction.Concat)
                    {
                        // Concat(Concat(?, ?), Concat(?, ?))

                        var arg1Args = new List <Expression>();

                        foreach (var arg in arg1.Arguments)
                        {
                            arg1Args.Add(Visit(arg));
                        }

                        var arg2Args = new List <Expression>();

                        foreach (var arg in arg2.Arguments)
                        {
                            arg2Args.Add(Visit(arg));
                        }

                        retval = new SqlFunctionCallExpression(functionCallExpression.Type, SqlFunction.Concat, (arg1Args.Concat(arg2Args)).ToArray());

                        return(retval);
                    }
                }
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
Exemple #25
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            var result = this.ResolveSqlFunction(functionCallExpression);

            if (result.treatAsOperator)
            {
                this.Write("(");

                if (result.functionPrefix != null)
                {
                    this.Write(result.functionPrefix);
                }

                for (int i = 0, n = result.arguments.Count - 1; i <= n; i++)
                {
                    var requiresGrouping = result.arguments[i] is SqlSelectExpression;

                    if (requiresGrouping)
                    {
                        this.Write("(");
                    }

                    this.Visit(result.arguments[i]);

                    if (requiresGrouping)
                    {
                        this.Write(")");
                    }

                    if (i != n)
                    {
                        this.Write(' ');
                        this.Write(result.functionName);
                        this.Write(' ');
                    }
                }

                if (result.functionSuffix != null)
                {
                    this.Write(result.functionSuffix);
                }

                this.Write(")");
            }
            else
            {
                this.Write(result.functionName);

                if (!result.excludeParenthesis)
                {
                    this.Write("(");
                }

                if (result.functionPrefix != null)
                {
                    this.Write(result.functionPrefix);
                }

                if (result.argsBefore != null && result.argsBefore.Length > 0)
                {
                    for (int i = 0, n = result.argsBefore.Length - 1; i <= n; i++)
                    {
                        this.Write(this.ParameterIndicatorPrefix);
                        this.Write(ParamNamePrefix);
                        this.Write(this.parameterValues.Count);
                        this.parameterValues.Add(new Tuple <Type, object>(result.argsBefore[i].Item1, result.argsBefore[i].Item2));

                        if (i != n || (functionCallExpression.Arguments.Count > 0))
                        {
                            this.Write(", ");
                        }
                    }
                }

                for (int i = 0, n = result.arguments.Count - 1; i <= n; i++)
                {
                    this.Visit(result.arguments[i]);

                    if (i != n || (result.argsAfter != null && result.argsAfter.Length > 0))
                    {
                        this.Write(", ");
                    }
                }

                if (result.argsAfter != null && result.argsAfter.Length > 0)
                {
                    for (int i = 0, n = result.argsAfter.Length - 1; i <= n; i++)
                    {
                        this.Write(this.ParameterIndicatorPrefix);
                        this.Write(ParamNamePrefix);
                        this.Write(this.parameterValues.Count);
                        this.parameterValues.Add(new Tuple <Type, object>(result.argsAfter[i].Item1, result.argsAfter[i].Item2));

                        if (i != n)
                        {
                            this.Write(", ");
                        }
                    }
                }

                if (result.functionSuffix != null)
                {
                    this.Write(result.functionSuffix);
                }

                if (!result.excludeParenthesis)
                {
                    this.Write(")");
                }
            }

            return(functionCallExpression);
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            switch (functionCallExpression.Function)
            {
            case SqlFunction.Hour:
                Write("DATEPART(hour, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.Minute:
                Write("DATEPART(minute, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.Second:
                Write("DATEPART(second, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DayOfWeek:
                Write("DATEPART(weekday, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DayOfMonth:
                Write("DATEPART(day, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DayOfYear:
                Write("DATEPART(dayofyear, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.Date:
                Write("CONVERT(date, ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddDays:
                Write("DATEADD(DAY, ");
                Visit(functionCallExpression.Arguments[1]);
                Write(", ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddMonths:
                Write("DATEADD(MONTH, ");
                Visit(functionCallExpression.Arguments[1]);
                Write(", ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddYears:
                Write("DATEADD(YEAR, ");
                Visit(functionCallExpression.Arguments[1]);
                Write(", ");
                Visit(functionCallExpression.Arguments[0]);
                Write(")");
                return(functionCallExpression);

            case SqlFunction.DateTimeAddTimeSpan:
                Write("DATEADD(DAY, ");
                Write("CAST(");
                Visit(functionCallExpression.Arguments[1]);
                Write(" AS BIGINT)");
                Write(" / CAST(864000000000 AS BIGINT)");
                Write(", DATEADD(MS, ");
                Write("CAST(");
                Visit(functionCallExpression.Arguments[1]);
                Write(" AS BIGINT)");
                Write(" / CAST(10000 AS BIGINT) % 86400000, ");
                Visit(functionCallExpression.Arguments[0]);
                Write("))");
                return(functionCallExpression);
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            if (functionCallExpression.Function == SqlFunction.IsNull)
            {
                if (functionCallExpression.Arguments[0].NodeType == ExpressionType.Constant)
                {
                    return(Expression.Constant(((ConstantExpression)functionCallExpression.Arguments[0]).Value == null));
                }

                return(functionCallExpression);
            }
            else if (functionCallExpression.Function == SqlFunction.IsNotNull)
            {
                if (functionCallExpression.Arguments[0].NodeType == ExpressionType.Constant)
                {
                    return(Expression.Constant(((ConstantExpression)functionCallExpression.Arguments[0]).Value != null));
                }

                return(functionCallExpression);
            }
            else if (functionCallExpression.Function == SqlFunction.In)
            {
                var value = this.Visit(functionCallExpression.Arguments[1]) as ConstantExpression;

                var sqlValuesEnumerable = value?.Value as SqlValuesEnumerable;

                if (sqlValuesEnumerable?.IsEmpty() == true)
                {
                    return(Expression.Constant(false));
                }

                return(functionCallExpression);
            }
            else if (functionCallExpression.Function == SqlFunction.Concat)
            {
                var visitedArguments = this.VisitExpressionList(functionCallExpression.Arguments);

                if (visitedArguments.All(c => c is ConstantExpression))
                {
                    string result;

                    switch (functionCallExpression.Arguments.Count)
                    {
                    case 2:
                        result = string.Concat((string)((ConstantExpression)visitedArguments[0]).Value, (string)((ConstantExpression)visitedArguments[1]).Value);
                        break;

                    case 3:
                        result = string.Concat((string)((ConstantExpression)visitedArguments[0]).Value, (string)((ConstantExpression)visitedArguments[1]).Value, (string)((ConstantExpression)visitedArguments[2]).Value);
                        break;

                    case 4:
                        result = string.Concat((string)((ConstantExpression)visitedArguments[0]).Value, (string)((ConstantExpression)visitedArguments[1]).Value, (string)((ConstantExpression)visitedArguments[2]).Value, (string)((ConstantExpression)visitedArguments[3]).Value);
                        break;

                    default:
                        result = visitedArguments
                                 .Cast <ConstantExpression>()
                                 .Select(c => c.Value)
                                 .Aggregate(new StringBuilder(), (s, c) => s.Append(c))
                                 .ToString();
                        break;
                    }

                    return(Expression.Constant(result));
                }
            }

            return(base.VisitFunctionCall(functionCallExpression));
        }
        protected override FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionCallExpression)
        {
            var function  = functionCallExpression.Function;
            var arguments = functionCallExpression.Arguments;

            switch (function)
            {
            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%Y-%m-%d %H:%M:%f0000", "now"), null, arguments));

            case SqlFunction.Concat:
                return(new FunctionResolveResult("||", true, arguments));

            case SqlFunction.ServerNow:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%Y-%m-%d %H:%M:%f0000", "now", "localtime"), null, arguments));

            case SqlFunction.TimeSpanFromSeconds:
                return(new FunctionResolveResult("", false, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[0], Expression.Constant(" seconds")))
                {
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromMinutes:
                return(new FunctionResolveResult("", false, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[0], Expression.Constant(" minutes")))
                {
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromHours:
                return(new FunctionResolveResult("", false, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[0], Expression.Constant(" hours")))
                {
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromDays:
                return(new FunctionResolveResult("", false, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[0], Expression.Constant(" days")))
                {
                    excludeParenthesis = true
                });

            case SqlFunction.DateTimeAddTimeSpan:
                return(new FunctionResolveResult("STRFTIME", false, Expression.Constant("%Y-%m-%d %H:%M:%f0000"), arguments[0], arguments[1]));

            case SqlFunction.Year:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%Y"), null, arguments));

            case SqlFunction.Month:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%m"), null, arguments));

            case SqlFunction.Week:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%W"), null, arguments));

            case SqlFunction.DayOfYear:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%j"), null, arguments));

            case SqlFunction.DayOfMonth:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%d"), null, arguments));

            case SqlFunction.DayOfWeek:
                return(new FunctionResolveResult("STRFTIME", false, FunctionResolveResult.MakeArguments("%w"), null, arguments));

            case SqlFunction.Substring:
                return(new FunctionResolveResult("SUBSTR", false, arguments));

            case SqlFunction.TrimLeft:
                return(new FunctionResolveResult("LTRIM", false, arguments));

            case SqlFunction.TrimRight:
                return(new FunctionResolveResult("RTRIM", false, arguments));
            }

            return(base.ResolveSqlFunction(functionCallExpression));
        }
Exemple #29
0
        protected virtual FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionExpression)
        {
            var function  = functionExpression.Function;
            var arguments = functionExpression.Arguments;

            switch (function)
            {
            case SqlFunction.IsNull:
                return(new FunctionResolveResult("", true, arguments)
                {
                    functionSuffix = " IS NULL"
                });

            case SqlFunction.IsNotNull:
                return(new FunctionResolveResult("", true, arguments)
                {
                    functionSuffix = " IS NOT NULL"
                });

            case SqlFunction.In:
                return(new FunctionResolveResult("IN", true, arguments));

            case SqlFunction.Exists:
                return(new FunctionResolveResult("EXISTSOPERATOR", true, arguments)
                {
                    functionPrefix = " EXISTS "
                });

            case SqlFunction.UserDefined:
                return(new FunctionResolveResult(functionExpression.UserDefinedFunctionName, false, arguments));

            case SqlFunction.Coalesce:
                return(new FunctionResolveResult("COALESCE", false, arguments));

            case SqlFunction.Like:
                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, arguments));

            case SqlFunction.CompareObject:
                var expressionType = (ExpressionType)((ConstantExpression)arguments[0]).Value;
                var args           = new Expression[2];

                args[0] = arguments[1];
                args[1] = arguments[2];

                switch (expressionType)
                {
                case ExpressionType.LessThan:
                    return(new FunctionResolveResult("<", true, args.ToReadOnlyList()));

                case ExpressionType.LessThanOrEqual:
                    return(new FunctionResolveResult("<=", true, args.ToReadOnlyList()));

                case ExpressionType.GreaterThan:
                    return(new FunctionResolveResult(">", true, args.ToReadOnlyList()));

                case ExpressionType.GreaterThanOrEqual:
                    return(new FunctionResolveResult(">=", true, args.ToReadOnlyList()));
                }
                throw new InvalidOperationException();

            case SqlFunction.NotLike:
                return(new FunctionResolveResult("NOT " + this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, arguments));

            case SqlFunction.ServerNow:
                return(new FunctionResolveResult("NOW", false, arguments));

            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("UTCNOW", false, arguments));

            case SqlFunction.StartsWith:
            {
                Expression newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[1], Expression.Constant("%"));
                newArgument = SqlRedundantFunctionCallRemover.Remove(newArgument);

                var list = new List <Expression>
                {
                    arguments[0],
                    newArgument
                };

                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyList()));
            }

            case SqlFunction.ContainsString:
            {
                Expression newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, arguments[1], Expression.Constant("%"));
                newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Constant("%"), newArgument);
                newArgument = SqlRedundantFunctionCallRemover.Remove(newArgument);

                var list = new List <Expression>
                {
                    arguments[0],
                    newArgument
                };

                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyList()));
            }

            case SqlFunction.EndsWith:
            {
                Expression newArgument = new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Constant("%"), arguments[1]);
                newArgument = SqlRedundantFunctionCallRemover.Remove(newArgument);

                var list = new List <Expression>
                {
                    arguments[0],
                    newArgument
                };

                return(new FunctionResolveResult(this.sqlDialect.GetSyntaxSymbolString(SqlSyntaxSymbol.Like), true, list.ToReadOnlyList()));
            }

            default:
                return(new FunctionResolveResult(function.ToString().ToUpper(), false, arguments));
            }
        }
        protected override FunctionResolveResult ResolveSqlFunction(SqlFunctionCallExpression functionCallExpression)
        {
            var function  = functionCallExpression.Function;
            var arguments = functionCallExpression.Arguments;

            switch (function)
            {
            case SqlFunction.ServerUtcNow:
                return(new FunctionResolveResult("(NOW() at time zone 'utc')", false, arguments)
                {
                    excludeParenthesis = true
                });

            case SqlFunction.TimeSpanFromSeconds:
                return(new FunctionResolveResult("", true, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Call(arguments[0], MethodInfoFastRef.ObjectToStringMethod), Expression.Constant(" seconds")))
                {
                    functionSuffix = "::interval"
                });

            case SqlFunction.TimeSpanFromMinutes:
                return(new FunctionResolveResult("", true, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Call(arguments[0], MethodInfoFastRef.ObjectToStringMethod), Expression.Constant(" minutes")))
                {
                    functionSuffix = "::interval"
                });

            case SqlFunction.TimeSpanFromHours:
                return(new FunctionResolveResult("", true, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Call(arguments[0], MethodInfoFastRef.ObjectToStringMethod), Expression.Constant(" hours")))
                {
                    functionSuffix = "::interval"
                });

            case SqlFunction.TimeSpanFromDays:
                return(new FunctionResolveResult("", true, new SqlFunctionCallExpression(typeof(string), SqlFunction.Concat, Expression.Call(arguments[0], MethodInfoFastRef.ObjectToStringMethod), Expression.Constant(" days")))
                {
                    functionSuffix = "::interval"
                });

            case SqlFunction.DateTimeAddTimeSpan:
                return(new FunctionResolveResult("+", true, arguments));

            case SqlFunction.Concat:
                return(new FunctionResolveResult("||", true, arguments));

            case SqlFunction.TrimLeft:
                return(new FunctionResolveResult("LTRIM", false, arguments));

            case SqlFunction.TrimRight:
                return(new FunctionResolveResult("RTRIM", false, arguments));

            case SqlFunction.Round:
                return(new FunctionResolveResult("ROUND", false, arguments));

            case SqlFunction.DayOfMonth:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("DAY"), null, arguments));

            case SqlFunction.DayOfWeek:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("DOW"), null, arguments));

            case SqlFunction.DayOfYear:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("DOY"), null, arguments));

            case SqlFunction.Year:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("YEAR"), null, arguments));

            case SqlFunction.Month:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("MONTH"), null, arguments));

            case SqlFunction.Hour:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("HOUR"), null, arguments));

            case SqlFunction.Second:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("SECOND"), null, arguments));

            case SqlFunction.Minute:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("MINUTE"), null, arguments));

            case SqlFunction.Week:
                return(new FunctionResolveResult("date_part", false, FunctionResolveResult.MakeArguments("WEEK"), null, arguments));

            case SqlFunction.StringLength:
                return(new FunctionResolveResult("char_length", false, arguments));
            }

            return(base.ResolveSqlFunction(functionCallExpression));
        }