internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { // process the arguments SqlExpression result = base.VisitFunctionCall(fc); if (result is SqlFunctionCall) { SqlFunctionCall resultFunctionCall = (SqlFunctionCall)result; if (resultFunctionCall.Name == "LEN") { SqlExpression expr = resultFunctionCall.Arguments[0]; if (expr.SqlType.IsLargeType && !expr.SqlType.SupportsLength) { result = sql.DATALENGTH(expr); if (expr.SqlType.IsUnicodeType) { result = sql.ConvertToInt(sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression))); } } } // If the return type of the sql function is not compatible with // the expected CLR type of the function, inject a conversion. This // step must be performed AFTER SqlRetyper has run. Type clrType = resultFunctionCall.SqlType.GetClosestRuntimeType(); bool skipConversion = SqlMethodTransformer.SkipConversionForDateAdd(resultFunctionCall.Name, resultFunctionCall.ClrType, clrType); if ((resultFunctionCall.ClrType != clrType) && !skipConversion) { result = sql.ConvertTo(resultFunctionCall.ClrType, resultFunctionCall); } } return result; }
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { for (int i = 0, n = fc.Arguments.Count; i < n; i++) { fc.Arguments[i] = this.FetchExpression(fc.Arguments[i]); } return fc; }
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { if (fc.Name == "LEN") { bool changed; fc.Arguments[0] = ConvertToMax(fc.Arguments[0],out changed); if (fc.Arguments[0].SqlType.IsLargeType) { this.annotations.Add(fc, new SqlServerCompatibilityAnnotation( Strings.LenOfTextOrNTextNotSupported(fc.SourceExpression), SqlProvider.ProviderMode.Sql2000)); } } return base.VisitFunctionCall(fc); }
internal virtual SqlExpression VisitFunctionCall(SqlFunctionCall fc) { for (int i = 0, n = fc.Arguments.Count; i < n; i++) { fc.Arguments[i] = this.VisitExpression(fc.Arguments[i]); } return fc; }
internal override SqlExpression DATEPART(string partName, SqlExpression expr) { var args = new[] { expr }; var s = expr.SourceExpression; SqlExpression arg; IProviderType sqlType = null; Type clrType = typeof(int); sqlType = TypeProvider.From(typeof(string)); switch (partName.ToUpper()) { case "HOUR": arg = ValueFromObject("HH24", true, s); break; case "MINUTE": arg = ValueFromObject("MI", true, s); break; case "SECOND": arg = ValueFromObject("SS", true, s); break; case "DAY": args = new[] { VariableFromName("DAY FROM", s), expr }; return(new SqlFunctionCall(clrType, sqlType, "EXTRACT", args, s) { Comma = false }); case "MONTH": args = new[] { VariableFromName("MONTH FROM", s), expr }; return(new SqlFunctionCall(clrType, sqlType, "EXTRACT", args, s) { Comma = false }); case "YEAR": args = new[] { VariableFromName("YEAR FROM", s), expr }; return(new SqlFunctionCall(clrType, sqlType, "EXTRACT", args, s) { Comma = false }); case "DAYOFWEEK": clrType = typeof(DayOfWeek); sqlType = TypeProvider.From(typeof(int)); arg = ValueFromObject("D", true, s); var func = new SqlFunctionCall(clrType, sqlType, "TO_CHAR", new[] { expr, arg }, s); return(new SqlBinary(SqlNodeType.Sub, clrType, sqlType, func, ValueFromObject(1, s))); case "DAYOFYEAR": arg = ValueFromObject("DDD", true, s); break; case "TIMEOFDAY": arg = ValueFromObject("DDD", true, s); break; default: throw SqlClient.Error.MethodHasNoSupportConversionToSql(partName); } return(new SqlFunctionCall(clrType, sqlType, "TO_CHAR", new[] { expr, arg }, s)); }
internal abstract ProviderType ReturnTypeOfFunction(SqlFunctionCall functionCall);
/// <inheritdoc/> public override void Visit(SqlFunctionCall node) { switch (node.FunctionType) { case SqlFunctionType.Truncate: var argument = node.Arguments[0]; SqlDml.FunctionCall("TRUNCATE", argument, SqlDml.Literal(0)).AcceptVisitor(this); return; case SqlFunctionType.Concat: var exprs = new SqlExpression[node.Arguments.Count]; node.Arguments.CopyTo(exprs, 0); Visit(SqlDml.Concat(exprs)); return; case SqlFunctionType.CharLength: SqlDml.FunctionCall(translator.Translate(SqlFunctionType.CharLength), node.Arguments[0]).AcceptVisitor(this); // SqlDml.CharLength(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.PadLeft: case SqlFunctionType.PadRight: SqlHelper.GenericPad(node).AcceptVisitor(this); return; case SqlFunctionType.Rand: SqlDml.FunctionCall(translator.Translate(SqlFunctionType.Rand)).AcceptVisitor(this); return; case SqlFunctionType.Square: SqlDml.Power(node.Arguments[0], 2).AcceptVisitor(this); return; case SqlFunctionType.IntervalToMilliseconds: Visit(CastToLong(node.Arguments[0]) / NanosecondsPerMillisecond); return; case SqlFunctionType.IntervalConstruct: case SqlFunctionType.IntervalToNanoseconds: Visit(CastToLong(node.Arguments[0])); return; case SqlFunctionType.DateTimeAddMonths: Visit(DateAddMonth(node.Arguments[0], node.Arguments[1])); return; case SqlFunctionType.DateTimeAddYears: Visit(DateAddYear(node.Arguments[0], node.Arguments[1])); return; case SqlFunctionType.DateTimeConstruct: Visit(DateAddDay(DateAddMonth(DateAddYear(SqlDml.Literal(new DateTime(2001, 1, 1)), node.Arguments[0] - 2001), node.Arguments[1] - 1), node.Arguments[2] - 1)); return; case SqlFunctionType.DateTimeToStringIso: Visit(DateTimeToStringIso(node.Arguments[0])); return; } base.Visit(node); }
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { if (fc.Name.Contains(".")) { // Assume UDF -- bracket the name. this.WriteName(fc.Name); } else { // No ".", so we assume it's a system function name and leave it alone. sb.Append(fc.Name); } sb.Append("("); for (int i = 0, n = fc.Arguments.Count; i < n; i++) { if (i > 0) sb.Append(", "); this.Visit(fc.Arguments[i]); } sb.Append(")"); return fc; }
internal static bool AreEqual(SqlNode node1, SqlNode node2) { if (node1 == node2) { return(true); } if ((node1 != null) && (node2 != null)) { if (node1.NodeType == SqlNodeType.SimpleCase) { node1 = UnwrapTrivialCaseExpression((SqlSimpleCase)node1); } if (node2.NodeType == SqlNodeType.SimpleCase) { node2 = UnwrapTrivialCaseExpression((SqlSimpleCase)node2); } if (node1.NodeType != node2.NodeType) { if (node1.NodeType == SqlNodeType.ExprSet) { SqlExprSet set = (SqlExprSet)node1; int num = 0; int count = set.Expressions.Count; while (num < count) { if (AreEqual(set.Expressions[num], node2)) { return(true); } num++; } } else if (node2.NodeType == SqlNodeType.ExprSet) { SqlExprSet set2 = (SqlExprSet)node2; int num3 = 0; int num4 = set2.Expressions.Count; while (num3 < num4) { if (AreEqual(node1, set2.Expressions[num3])) { return(true); } num3++; } } return(false); } if (node1.Equals(node2)) { return(true); } switch (node1.NodeType) { case SqlNodeType.Add: case SqlNodeType.And: case SqlNodeType.BitAnd: case SqlNodeType.BitOr: case SqlNodeType.BitXor: case SqlNodeType.Concat: case SqlNodeType.Div: case SqlNodeType.EQ: case SqlNodeType.EQ2V: case SqlNodeType.LE: case SqlNodeType.LT: case SqlNodeType.GE: case SqlNodeType.GT: case SqlNodeType.Mod: case SqlNodeType.Mul: case SqlNodeType.NE: case SqlNodeType.NE2V: case SqlNodeType.Or: case SqlNodeType.Sub: { SqlBinary binary = (SqlBinary)node1; SqlBinary binary2 = (SqlBinary)node2; if (!AreEqual(binary.Left, binary2.Left)) { return(false); } return(AreEqual(binary.Right, binary2.Right)); } case SqlNodeType.Alias: return(AreEqual(((SqlAlias)node1).Node, ((SqlAlias)node2).Node)); case SqlNodeType.AliasRef: return(AreEqual(((SqlAliasRef)node1).Alias, ((SqlAliasRef)node2).Alias)); case SqlNodeType.Avg: case SqlNodeType.BitNot: case SqlNodeType.ClrLength: case SqlNodeType.Count: case SqlNodeType.Covar: case SqlNodeType.IsNotNull: case SqlNodeType.IsNull: case SqlNodeType.Max: case SqlNodeType.Min: case SqlNodeType.Negate: case SqlNodeType.Not: case SqlNodeType.Not2V: case SqlNodeType.OuterJoinedValue: case SqlNodeType.Stddev: case SqlNodeType.Sum: case SqlNodeType.ValueOf: return(AreEqual(((SqlUnary)node1).Operand, ((SqlUnary)node2).Operand)); case SqlNodeType.Between: { SqlBetween between = (SqlBetween)node1; SqlBetween between2 = (SqlBetween)node1; if (!AreEqual(between.Expression, between2.Expression) || !AreEqual(between.Start, between2.Start)) { return(false); } return(AreEqual(between.End, between2.End)); } case SqlNodeType.Cast: case SqlNodeType.Convert: case SqlNodeType.Treat: { SqlUnary unary = (SqlUnary)node1; SqlUnary unary2 = (SqlUnary)node2; if ((unary.ClrType != unary2.ClrType) || !(unary.SqlType == unary2.SqlType)) { return(false); } return(AreEqual(unary.Operand, unary2.Operand)); } case SqlNodeType.ClientCase: { SqlClientCase case5 = (SqlClientCase)node1; SqlClientCase case6 = (SqlClientCase)node2; if (case5.Whens.Count == case6.Whens.Count) { int num9 = 0; int num10 = case5.Whens.Count; while (num9 < num10) { if (!AreEqual(case5.Whens[num9].Match, case6.Whens[num9].Match) || !AreEqual(case5.Whens[num9].Value, case6.Whens[num9].Value)) { return(false); } num9++; } return(true); } return(false); } case SqlNodeType.Column: { SqlColumn column = (SqlColumn)node1; SqlColumn column2 = (SqlColumn)node2; return((column == column2) || (((column.Expression != null) && (column2.Expression != null)) && AreEqual(column.Expression, column2.Expression))); } case SqlNodeType.ColumnRef: { SqlColumnRef cref = (SqlColumnRef)node1; SqlColumnRef ref3 = (SqlColumnRef)node2; return(GetBaseColumn(cref) == GetBaseColumn(ref3)); } case SqlNodeType.DiscriminatedType: { SqlDiscriminatedType type = (SqlDiscriminatedType)node1; SqlDiscriminatedType type2 = (SqlDiscriminatedType)node2; return(AreEqual(type.Discriminator, type2.Discriminator)); } case SqlNodeType.ExprSet: { SqlExprSet set3 = (SqlExprSet)node1; SqlExprSet set4 = (SqlExprSet)node2; if (set3.Expressions.Count == set4.Expressions.Count) { int num17 = 0; int num18 = set3.Expressions.Count; while (num17 < num18) { if (!AreEqual(set3.Expressions[num17], set4.Expressions[num17])) { return(false); } num17++; } return(true); } return(false); } case SqlNodeType.FunctionCall: { SqlFunctionCall call = (SqlFunctionCall)node1; SqlFunctionCall call2 = (SqlFunctionCall)node2; if (!(call.Name != call2.Name)) { if (call.Arguments.Count != call2.Arguments.Count) { return(false); } int num13 = 0; int num14 = call.Arguments.Count; while (num13 < num14) { if (!AreEqual(call.Arguments[num13], call2.Arguments[num13])) { return(false); } num13++; } return(true); } return(false); } case SqlNodeType.Link: { SqlLink link = (SqlLink)node1; SqlLink link2 = (SqlLink)node2; if (MetaPosition.AreSameMember(link.Member.Member, link2.Member.Member)) { if (!AreEqual(link.Expansion, link2.Expansion)) { return(false); } if (link.KeyExpressions.Count != link2.KeyExpressions.Count) { return(false); } int num15 = 0; int num16 = link.KeyExpressions.Count; while (num15 < num16) { if (!AreEqual(link.KeyExpressions[num15], link2.KeyExpressions[num15])) { return(false); } num15++; } return(true); } return(false); } case SqlNodeType.Like: { SqlLike like = (SqlLike)node1; SqlLike like2 = (SqlLike)node2; if (!AreEqual(like.Expression, like2.Expression) || !AreEqual(like.Pattern, like2.Pattern)) { return(false); } return(AreEqual(like.Escape, like2.Escape)); } case SqlNodeType.Member: if (((SqlMember)node1).Member != ((SqlMember)node2).Member) { return(false); } return(AreEqual(((SqlMember)node1).Expression, ((SqlMember)node2).Expression)); case SqlNodeType.OptionalValue: { SqlOptionalValue value2 = (SqlOptionalValue)node1; SqlOptionalValue value3 = (SqlOptionalValue)node2; return(AreEqual(value2.Value, value3.Value)); } case SqlNodeType.Parameter: return(node1 == node2); case SqlNodeType.SearchedCase: { SqlSearchedCase case3 = (SqlSearchedCase)node1; SqlSearchedCase case4 = (SqlSearchedCase)node2; if (case3.Whens.Count == case4.Whens.Count) { int num7 = 0; int num8 = case3.Whens.Count; while (num7 < num8) { if (!AreEqual(case3.Whens[num7].Match, case4.Whens[num7].Match) || !AreEqual(case3.Whens[num7].Value, case4.Whens[num7].Value)) { return(false); } num7++; } return(AreEqual(case3.Else, case4.Else)); } return(false); } case SqlNodeType.SimpleCase: { SqlSimpleCase case7 = (SqlSimpleCase)node1; SqlSimpleCase case8 = (SqlSimpleCase)node2; if (case7.Whens.Count == case8.Whens.Count) { int num11 = 0; int num12 = case7.Whens.Count; while (num11 < num12) { if (!AreEqual(case7.Whens[num11].Match, case8.Whens[num11].Match) || !AreEqual(case7.Whens[num11].Value, case8.Whens[num11].Value)) { return(false); } num11++; } return(true); } return(false); } case SqlNodeType.Table: return(((SqlTable)node1).MetaTable == ((SqlTable)node2).MetaTable); case SqlNodeType.TypeCase: { SqlTypeCase @case = (SqlTypeCase)node1; SqlTypeCase case2 = (SqlTypeCase)node2; if (AreEqual(@case.Discriminator, case2.Discriminator)) { if (@case.Whens.Count != case2.Whens.Count) { return(false); } int num5 = 0; int num6 = @case.Whens.Count; while (num5 < num6) { if (!AreEqual(@case.Whens[num5].Match, case2.Whens[num5].Match)) { return(false); } if (!AreEqual(@case.Whens[num5].TypeBinding, case2.Whens[num5].TypeBinding)) { return(false); } num5++; } return(true); } return(false); } case SqlNodeType.Variable: { SqlVariable variable = (SqlVariable)node1; SqlVariable variable2 = (SqlVariable)node2; return(variable.Name == variable2.Name); } case SqlNodeType.Value: return(object.Equals(((SqlValue)node1).Value, ((SqlValue)node2).Value)); } } return(false); }
//取消函数括号,即Limit(int,int) -> Limit int, int internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { switch (fc.Name) { case "Limit": { Debug.Assert(fc.Arguments.Count == 2); bool limited = false; if (!(fc.Arguments[0] is SqlValue) || (int)((SqlValue)fc.Arguments[0]).Value > 0) { sb.Append("LIMIT "); this.Visit(fc.Arguments[0]); sb.Append(" "); limited = true; } if (!(fc.Arguments[1] is SqlValue) || (int)((SqlValue)fc.Arguments[1]).Value > 0) { if (!limited) { sb.Append("LIMIT 18446744073709551615 "); } sb.Append("OFFSET "); this.Visit(fc.Arguments[1]); } return(fc); } //case "DATE_FORMAT": // sb.Append("CAST("); // var result = base.VisitFunctionCall(fc); // sb.Append(" AS SIGNED)"); // return result; //case "Date": // sb.Append("Date("); // Visit(fc.Arguments[0]); // sb.Append(")"); // return fc; case "AddDays": case "AddHours": case "AddMinutes": case "AddMonths": case "AddSeconds": case "AddYears": sb.Append("DATE_ADD("); Visit(fc.Arguments[0]); sb.Append(", INTERVAL "); Visit(fc.Arguments[1]); sb.Append(" "); sb.Append(((SqlValue)fc.Arguments[2]).Value); sb.Append(")"); return(fc); //case "AddHours": // sb.Append("DATE_ADD("); // Visit(fc.Arguments[0]); // sb.Append(", INTERVAL "); // Visit(fc.Arguments[1]); // sb.Append(" DAY)"); // return fc; } return(base.VisitFunctionCall(fc)); }
protected virtual SqlExpression VisitFunction(SqlFunctionCall expr) { return expr; }
public override void Visit(SqlFunctionCall node) { switch (node.FunctionType) { case SqlFunctionType.PadLeft: case SqlFunctionType.PadRight: SqlHelper.GenericPad(node).AcceptVisitor(this); return; case SqlFunctionType.DateTimeOffsetAddYears: case SqlFunctionType.DateTimeAddYears: DateTimeAddComponent(node.Arguments[0], node.Arguments[1], true).AcceptVisitor(this); return; case SqlFunctionType.DateTimeOffsetAddMonths: case SqlFunctionType.DateTimeAddMonths: DateTimeAddComponent(node.Arguments[0], node.Arguments[1], false).AcceptVisitor(this); return; case SqlFunctionType.IntervalConstruct: IntervalConstruct(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeConstruct: DateTimeConstruct(node.Arguments[0], node.Arguments[1], node.Arguments[2]).AcceptVisitor(this); return; case SqlFunctionType.IntervalAbs: SqlHelper.IntervalAbs(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.IntervalToMilliseconds: SqlHelper.IntervalToMilliseconds(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.IntervalToNanoseconds: SqlHelper.IntervalToNanoseconds(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.Position: Position(node.Arguments[0], node.Arguments[1]).AcceptVisitor(this); return; case SqlFunctionType.CharLength: SqlDml.Coalesce(SqlDml.FunctionCall("LENGTH", node.Arguments[0]), 0).AcceptVisitor(this); return; case SqlFunctionType.DateTimeToStringIso: DateTimeToStringIso(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeOffsetConstruct: DateTimeOffsetConstruct(node.Arguments[0], node.Arguments[1]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeOffsetTimeOfDay: DateTimeOffsetTimeOfDay(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeOffsetToLocalTime: DateTimeOffsetToLocalTime(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeToDateTimeOffset: DateTimeToDateTimeOffset(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeOffsetToUtcTime: DateTimeOffsetToUtcTime(node.Arguments[0]).AcceptVisitor(this); return; default: base.Visit(node); return; } }
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { switch (fc.Name) { case "SkipTake": { Debug.Assert(fc.Arguments.Count == 2); var skip = (int)((SqlValue)fc.Arguments[0]).Value; var take = (int)((SqlValue)fc.Arguments[1]).Value; var str = string.Empty; if (take >= 0) { sb.Append("FIRST "); sb.Append(take); str = " "; } if (skip >= 0) { sb.Append(str); sb.Append("SKIP "); sb.Append(skip); } return(fc); } case "LEN": case "DATALENGTH": sb.Append("OCTET_LENGTH( "); Visit(fc.Arguments[0]); sb.Append(" ) "); return(fc); case "TrimEnd": sb.Append("TRIM( TRAILING From "); Visit(fc.Arguments[0]); sb.Append(" )"); return(fc); case "TrimStart": sb.Append("TRIM( LEADING From "); Visit(fc.Arguments[0]); sb.Append(" )"); return(fc); case "SUBSTRING": sb.Append("SUBSTRING( "); Visit(fc.Arguments[0]); sb.Append(" FROM "); Visit(fc.Arguments[1]); if (fc.Arguments.Count > 2) { sb.Append(" FOR "); Visit(fc.Arguments[2]); } sb.Append(")"); return(fc); case "Date": sb.Append("CAST ("); Visit(fc.Arguments[0]); sb.Append(" AS DATE)"); return(fc); } //if (fc.Name.StartsWith("GEN_ID")) //{ // sb.Append(fc.Name); // sb.Append(" FROM RDB$DATABASE"); // return fc; //} return(base.VisitFunctionCall(fc)); }
protected override SqlExpression VisitFunction(SqlFunctionCall expr) { if (expr.Name.Contains(".")) WriteName(expr.Name); else _builder.Append(expr.Name); _builder.Append("("); for (int i = 0; i < expr.Arguments.Expressions.Count; ++i) { if (i > 0) _builder.Append(", "); Visit(expr.Arguments.Expressions[i]); } _builder.Append(")"); return expr; }
internal override ProviderType ReturnTypeOfFunction(SqlFunctionCall functionCall) { var argumentTypes = this.GetArgumentTypes(functionCall); SqlType arg0 = (SqlType)argumentTypes[0]; SqlType arg1 = argumentTypes.Length > 1 ? (SqlType)argumentTypes[1] : (SqlType)null; switch (functionCall.Name) { case "LEN": case "DATALENGTH": switch (arg0.SqlDbType) { case SqlDbType.NVarChar: case SqlDbType.VarChar: case SqlDbType.VarBinary: if (arg0.IsLargeType) { return(SqlTypeSystem.Create(SqlDbType.BigInt)); } else { return(SqlTypeSystem.Create(SqlDbType.Int)); } default: return(SqlTypeSystem.Create(SqlDbType.Int)); } case "ABS": case "SIGN": case "ROUND": case "CEILING": case "FLOOR": case "POWER": switch (arg0.SqlDbType) { case SqlDbType.TinyInt: case SqlDbType.Int: case SqlDbType.SmallInt: return(SqlTypeSystem.Create(SqlDbType.Int)); case SqlDbType.Float: case SqlDbType.Real: return(SqlTypeSystem.Create(SqlDbType.Float)); default: return(arg0); } case "PATINDEX": case "CHARINDEX": if (arg1.IsLargeType) { return(SqlTypeSystem.Create(SqlDbType.BigInt)); } return(SqlTypeSystem.Create(SqlDbType.Int)); case "SUBSTRING": if (functionCall.Arguments[2].NodeType == SqlNodeType.Value) { SqlValue val = (SqlValue)functionCall.Arguments[2]; if (val.Value is int) { switch (arg0.SqlDbType) { case SqlDbType.NVarChar: case SqlDbType.NChar: case SqlDbType.VarChar: case SqlDbType.Char: return(SqlTypeSystem.Create(arg0.SqlDbType, (int)val.Value)); default: return(null); } } } switch (arg0.SqlDbType) { case SqlDbType.NVarChar: case SqlDbType.NChar: return(SqlTypeSystem.Create(SqlDbType.NVarChar)); case SqlDbType.VarChar: case SqlDbType.Char: return(SqlTypeSystem.Create(SqlDbType.VarChar)); default: return(null); } case "STUFF": // if the stuff call is an insertion and is strictly additive // (no deletion of characters) the return type is the same as // a concatenation if (functionCall.Arguments.Count == 4) { SqlValue delLength = functionCall.Arguments[2] as SqlValue; if (delLength != null && (int)delLength.Value == 0) { return(PredictTypeForBinary(SqlNodeType.Concat, functionCall.Arguments[0].SqlType, functionCall.Arguments[3].SqlType)); } } return(null); case "LOWER": case "UPPER": case "RTRIM": case "LTRIM": case "INSERT": case "REPLACE": case "LEFT": case "RIGHT": case "REVERSE": return(arg0); default: return(null); } }
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { SqlExpression[] args = new SqlExpression[fc.Arguments.Count]; for (int i = 0, n = fc.Arguments.Count; i < n; i++) { args[i] = this.VisitExpression(fc.Arguments[i]); } return new SqlFunctionCall(fc.ClrType, fc.SqlType, fc.Name, args, fc.SourceExpression); }
/// <inheritdoc/> public override void Visit(SqlFunctionCall node) { switch (node.FunctionType) { case SqlFunctionType.CharLength: (SqlDml.FunctionCall("DATALENGTH", node.Arguments) / 2).AcceptVisitor(this); return; case SqlFunctionType.PadLeft: case SqlFunctionType.PadRight: GenericPad(node).AcceptVisitor(this); return; case SqlFunctionType.Round: // Round should always be called with 2 arguments if (node.Arguments.Count == 1) { Visit(SqlDml.FunctionCall( translator.Translate(SqlFunctionType.Round), node.Arguments[0], SqlDml.Literal(0))); return; } break; case SqlFunctionType.Truncate: // Truncate is implemented as round(arg, 0, 1) call in MSSQL. // It's stupid, isn't it? Visit(SqlDml.FunctionCall( translator.Translate(SqlFunctionType.Round), node.Arguments[0], SqlDml.Literal(0), SqlDml.Literal(1))); return; case SqlFunctionType.Substring: if (node.Arguments.Count == 2) { node = SqlDml.Substring(node.Arguments[0], node.Arguments[1]); SqlExpression len = SqlDml.CharLength(node.Arguments[0]); node.Arguments.Add(len); Visit(node); return; } break; case SqlFunctionType.IntervalToMilliseconds: Visit(CastToLong(node.Arguments[0]) / NanosecondsPerMillisecond); return; case SqlFunctionType.IntervalConstruct: case SqlFunctionType.IntervalToNanoseconds: Visit(CastToLong(node.Arguments[0])); return; case SqlFunctionType.DateTimeAddMonths: Visit(DateAddMonth(node.Arguments[0], node.Arguments[1])); return; case SqlFunctionType.DateTimeAddYears: Visit(DateAddYear(node.Arguments[0], node.Arguments[1])); return; case SqlFunctionType.DateTimeTruncate: DateTimeTruncate(node.Arguments[0]).AcceptVisitor(this); return; case SqlFunctionType.DateTimeConstruct: Visit(DateAddDay(DateAddMonth(DateAddYear(SqlDml.Literal(new DateTime(2001, 1, 1)), node.Arguments[0] - 2001), node.Arguments[1] - 1), node.Arguments[2] - 1)); return; case SqlFunctionType.DateTimeToStringIso: Visit(DateTimeToStringIso(node.Arguments[0])); return; } base.Visit(node); }
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) { for (int i = 0, n = fc.Arguments.Count; i < n; i++) { fc.Arguments[i] = this.VisitExpression(fc.Arguments[i]); } if (fc.Arguments.Count > 0) { ProviderType oldType = fc.Arguments[0].SqlType; // if this has a real argument (not e.g. the symbol "DAY" in DATEDIFF(DAY,...)) if (oldType != null) { ProviderType newType = this.typeProvider.ReturnTypeOfFunction(fc); if (newType != null) { fc.SetSqlType(newType); } } } return fc; }
protected override SqlNode VisitMethodCall(MethodCallExpression mc) { //´¦Àí×Ö·û´®º¯Êý¡£ if (mc.Object != null && mc.Object.Type == typeof(string)) { switch (mc.Method.Name) { case "Trim": { var clrType = mc.Method.ReturnType; var expressions = new[] { VisitExpression(mc.Object) }; var node = new SqlFunctionCall(clrType, typeProvider.From(clrType), "Trim", expressions, dominatingExpression); return(node); } case "TrimStart": { var clrType = mc.Method.ReturnType; var expressions = new[] { VisitExpression(mc.Object) }; var node = new SqlFunctionCall(clrType, typeProvider.From(clrType), "LTrim", expressions, dominatingExpression); return(node); } case "TrimEnd": { var clrType = mc.Method.ReturnType; var expressions = new[] { VisitExpression(mc.Object) }; var node = new SqlFunctionCall(clrType, typeProvider.From(clrType), "RTrim", expressions, dominatingExpression); return(node); } case "Remove": { var clrType = mc.Method.ReturnType; Debug.Assert(clrType == typeof(string)); var startIndex = (int)((ConstantExpression)mc.Arguments[0]).Value; var arg1 = VisitExpression(mc.Object); var arg2 = VisitExpression(Expression.Constant(1)); var arg3 = VisitExpression(Expression.Constant(startIndex)); var left = new SqlFunctionCall(typeof(string), typeProvider.From(typeof(string)), "SUBSTR", new[] { arg1, arg2, arg3 }, dominatingExpression); if (mc.Arguments.Count == 2) { var count = (int)((ConstantExpression)mc.Arguments[1]).Value; arg2 = VisitExpression(Expression.Constant(startIndex + count)); SqlExpression right = new SqlFunctionCall(typeof(string), typeProvider.From(typeof(string)), "SUBSTR", new[] { arg1, arg2 }, dominatingExpression); var result = new SqlBinary(SqlNodeType.Add, clrType, typeProvider.From(clrType), left, right); return(result); } Debug.Assert(mc.Arguments.Count == 1); return(left); } case "Replace": { var clrType = mc.Method.ReturnType; var sqlType = typeProvider.From(clrType); Debug.Assert(clrType == typeof(string)); Debug.Assert(mc.Arguments.Count == 2); var sourceObject = VisitExpression(mc.Object); var oldValue = VisitExpression(mc.Arguments[0]); var newValue = VisitExpression(mc.Arguments[1]); var result = new SqlFunctionCall(clrType, sqlType, "Replace", new[] { sourceObject, oldValue, newValue }, dominatingExpression); return(result); } default: return(base.VisitMethodCall(mc)); } } return(base.VisitMethodCall(mc)); }