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); }
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 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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
protected override Expression VisitFunctionCall(SqlFunctionCallExpression functionCallExpression) { this.hashCode ^= (int)functionCallExpression.Function << 24; return(base.VisitFunctionCall(functionCallExpression)); }
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 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.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); }
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 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); }
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 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); }
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 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; }