Represents an SQL function call such as DATE, YEAR, SUBSTRING or ISNULL.
상속: SqlBaseExpression
		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 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);
		}
예제 #3
0
        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);
        }
예제 #4
0
		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);
			case SqlFunction.StringLength:
				return new FunctionResolveResult("LENGTH", false, arguments);
			}

			return base.ResolveSqlFunction(functionCallExpression);
		}
예제 #5
0
        protected virtual Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            var newArgs = VisitExpressionList(functionCallExpression.Arguments);

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

            return(functionCallExpression);
        }
예제 #6
0
        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);
        }
예제 #7
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)
		{
			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);
		}
예제 #9
0
        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);
        }
예제 #10
0
		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?.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, this.Visit(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 retval = new SqlSelectExpression(selectExpression.Type, selectExpression.Alias, outerColumns.ToReadOnlyCollection(), innerSelectWithRow, rowPredicate, null, null, selectExpression.Distinct, null, null, selectExpression.ForUpdate, selectExpression.Reverse, selectExpression.Into);

				return retval;
			}

			return base.VisitSelect(selectExpression);
		}
        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.Table, expression.ColumnNames, expression.ReturningAutoIncrementColumnNames, newValueExpressions);
                }
            }

            return expression;
        }
		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, new Expression[] { newProjection });
					}
				}
			}
			return base.VisitFunctionCall(functionCallExpression);
		}
예제 #13
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            SqlFunctionCallExpression current;

            if (!TryGetCurrent(functionCallExpression, out current))
            {
                return(functionCallExpression);
            }

            result = result && (current.Function == functionCallExpression.Function);

            if (result)
            {
                currentObject = current.Arguments;
                VisitExpressionList(functionCallExpression.Arguments);
                currentObject = current;
            }

            return(functionCallExpression);
        }
예제 #14
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 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);
        }
        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 Expression VisitFunctionCall(SqlFunctionCallExpression expression)
 {
     this.hashCode ^= expression.Function.GetHashCode();
     this.hashCode ^= expression.UserDefinedFunctionName?.GetHashCode() ?? 0;
     return base.VisitFunctionCall(expression);
 }
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression expression)
        {
            SqlFunctionCallExpression current;
            if (!TryGetCurrent(expression, out current))
            {
                return expression;
            }

            if (!(this.result &= current.Function == expression.Function))
            {
                return expression;
            }

            if (!(this.result &= object.Equals(current.UserDefinedFunctionName, expression.UserDefinedFunctionName)))
            {
                return expression;
            }

            if (!(this.result &= current.NodeType == expression.NodeType))
            {
                return expression;
            }

            if (!(this.result &= current.Type == expression.Type))
            {
                return expression;
            }

            this.currentObject = current.Arguments;
            this.VisitExpressionList(expression.Arguments);
            if (!this.result)
            {
                return expression;
            }

            this.currentObject = current;
            return expression;
        }
		protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
		{
			if (functionCallExpression.Function == SqlFunction.IsNull)
			{
				ConstantExpression constantExpression;

				if ((constantExpression = this.Visit(functionCallExpression.Arguments[0]).StripAndGetConstant()) != null)
				{
					return Expression.Constant(constantExpression.Value == null);
				}

				return functionCallExpression;
			}
			else if (functionCallExpression.Function == SqlFunction.IsNotNull)
			{
				ConstantExpression constantExpression;

				if ((constantExpression = this.Visit(functionCallExpression.Arguments[0]).StripAndGetConstant()) != null)
				{
					return Expression.Constant(constantExpression.Value != null);
				}

				return functionCallExpression;
			}
			else if (functionCallExpression.Function == SqlFunction.In)
			{
				var value = this.Visit(functionCallExpression.Arguments[1]).StripAndGetConstant();
				
				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.StripAndGetConstant() != null))
				{
					string result;
					
					switch (functionCallExpression.Arguments.Count)
					{
					case 2:
						result = string.Concat((string)visitedArguments[0].StripAndGetConstant().Value, (string)visitedArguments[1].StripAndGetConstant().Value);
						break;
					case 3:
						result = string.Concat((string)visitedArguments[0].StripAndGetConstant().Value, (string)visitedArguments[1].StripAndGetConstant().Value, (string)visitedArguments[2].StripAndGetConstant().Value);
						break;
					case 4:
						result = string.Concat((string)visitedArguments[0].StripAndGetConstant().Value, (string)visitedArguments[1].StripAndGetConstant().Value, (string)((ConstantExpression)visitedArguments[2]).Value, (string)visitedArguments[3].StripAndGetConstant().Value);
						break;
					default:
						result = visitedArguments
								.Select(c => c.StripAndGetConstant().Value)
								.Aggregate(new StringBuilder(), (s, c) => s.Append(c))
								.ToString();
						break;
					}

					return Expression.Constant(result);
				}
			}
			
			return base.VisitFunctionCall(functionCallExpression);
		}
예제 #20
0
        protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression)
        {
            this.hashCode ^= (int)functionCallExpression.Function << 24;

            return(base.VisitFunctionCall(functionCallExpression));
        }
예제 #21
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);
		}
예제 #22
0
		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);
		}
예제 #23
0
        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);
        }
예제 #24
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);
        }
예제 #25
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 = this.Visit(functionCallExpression.Arguments[0]);
                        var arg2Args = new List<Expression>();

                        foreach (var arg in arg2.Arguments)
                        {
                            arg2Args.Add(this.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 = this.Visit(functionCallExpression.Arguments[1]);
                        var arg1Args = new List<Expression>();

                        foreach (var arg in arg1.Arguments)
                        {
                            arg1Args.Add(this.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(this.Visit(arg));
                        }

                        var arg2Args = new List<Expression>();

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

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

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

            return base.ResolveSqlFunction(functionCallExpression);
        }
예제 #27
0
		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;
		}
예제 #28
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 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 placeholderValue = this.Visit(functionCallExpression.Arguments[1]) as SqlConstantPlaceholderExpression;

                if (placeholderValue != null)
                {
                    value = placeholderValue.ConstantExpression;
                }

                if (value != null)
                {
                    if (value.Type.IsArray)
                    {
                        if (((Array)value.Value).Length == 0)
                        {
                            return Expression.Constant(false, functionCallExpression.Type);
                        }
                    }
                    else if (typeof(ICollection<>).IsAssignableFromIgnoreGenericParameters(value.Type))
                    {
                        // TODO: Use cached dynamic method instead of reflection call

                        int count;
                        Func<object, int> getter;

                        if (GenericListCountGetters.TryGetValue(value.Type, out getter))
                        {
                            count = getter(value.Value);
                        }

                        var newGenericListCountGetters = new Dictionary<Type, Func<object, int>>();

                        var type = value.Type.WalkHierarchy(true, false).FirstOrDefault(c => c.Name == typeof(ICollection<>).Name);

                        var prop = type.GetProperty("Count");

                        foreach (var kv in GenericListCountGetters)
                        {
                            newGenericListCountGetters[kv.Key] = kv.Value;
                        }

                        var param = Expression.Parameter(typeof(object), "value");
                        Expression body = Expression.Convert(param, value.Type);
                        body = Expression.Property(body, prop);
                        getter = (Func<object, int>)Expression.Lambda(body, param).Compile();

                        count = getter(value.Value);

                        newGenericListCountGetters[value.Type] = getter;

                        GenericListCountGetters = newGenericListCountGetters;

                        if (count == 0)
                        {
                            return Expression.Constant(false, functionCallExpression.Type);
                        }
                    }
                    else if (typeof(IEnumerable).IsAssignableFrom(value.Type))
                    {
                        if (IsEmpty((IEnumerable)value.Value))
                        {
                            return Expression.Constant(false, functionCallExpression.Type);
                        }
                    }
                }

                return functionCallExpression;
            }
            else if (functionCallExpression.Function == SqlFunction.Concat)
            {
                var ok = true;
                List<Expression> arguments = null;

                foreach (var arg in functionCallExpression.Arguments)
                {
                    var constantExpression = this.Visit(arg) as ConstantExpression;

                    if (constantExpression == null)
                    {
                        ok = false;

                        break;
                    }
                    else
                    {
                        if (arguments == null)
                        {
                            arguments = new List<Expression>();
                        }

                        arguments.Add(constantExpression);
                    }
                }

                if (ok)
                {
                    string result;
                    switch (functionCallExpression.Arguments.Count)
                    {
                        case 2:
                            result = String.Concat((string)((ConstantExpression)arguments[0]).Value, (string)((ConstantExpression)arguments[1]).Value);
                            break;
                        case 3:
                            result = String.Concat((string)((ConstantExpression)arguments[0]).Value, (string)((ConstantExpression)arguments[1]).Value, (string)((ConstantExpression)arguments[2]).Value);
                            break;
                        case 4:
                            result = String.Concat((string)((ConstantExpression)arguments[0]).Value, (string)((ConstantExpression)arguments[1]).Value, (string)((ConstantExpression)arguments[2]).Value, (string)((ConstantExpression)arguments[3]).Value);
                            break;
                        default:
                            var builder = new StringBuilder();
                            foreach (var arg in functionCallExpression.Arguments)
                            {
                                var constantExpression = (ConstantExpression)arg;
                                var value = (string)constantExpression.Value;

                                builder.Append(value);
                            }
                            result = builder.ToString();
                            break;
                    }

                    return Expression.Constant(result);
                }
            }

            return base.VisitFunctionCall(functionCallExpression);
        }
예제 #30
0
 protected override Expression VisitFunctionCall(SqlFunctionCallExpression expression)
 {
     this.hashCode ^= expression.Function.GetHashCode();
     this.hashCode ^= expression.UserDefinedFunctionName?.GetHashCode() ?? 0;
     return(base.VisitFunctionCall(expression));
 }
예제 #31
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;
        }