internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { if(mc.Arguments.Count == 2 && mc.Method.Name == "op_Equality") { var r = mc.Arguments[1]; if(r.NodeType == SqlNodeType.Value) { var v = (SqlValue)r; v.SetSqlType(mc.Arguments[0].SqlType); } } return base.VisitMethodCall(mc); }
private static MethodSupport GetSqlMethodsMethodSupport(SqlMethodCall mc) { if(mc.Method.IsStatic && mc.Method.DeclaringType == typeof(SqlMethods)) { if(mc.Method.Name.StartsWith("DateDiff", StringComparison.Ordinal) && mc.Arguments.Count == 2) { foreach(string datePart in dateParts) { if(mc.Method.Name == "DateDiff" + datePart) { if(mc.Arguments.Count == 2) { return MethodSupport.Method; } else { return MethodSupport.MethodGroup; } } } } else if(mc.Method.Name == "Like") { if(mc.Arguments.Count == 2) { return MethodSupport.Method; } else if(mc.Arguments.Count == 3) { return MethodSupport.Method; } return MethodSupport.MethodGroup; } else if(mc.Method.Name == "RawLength") { return MethodSupport.Method; } } return MethodSupport.None; }
internal virtual SqlExpression VisitMethodCall(SqlMethodCall mc) { mc.Object = this.VisitExpression(mc.Object); for (int i = 0, n = mc.Arguments.Count; i < n; i++) { mc.Arguments[i] = this.VisitExpression(mc.Arguments[i]); } return mc; }
private SqlExpression ExpandTogether(List<SqlExpression> exprs) { switch(exprs[0].NodeType) { case SqlNodeType.MethodCall: { SqlMethodCall[] mcs = new SqlMethodCall[exprs.Count]; for(int i = 0; i < mcs.Length; ++i) { mcs[i] = (SqlMethodCall)exprs[i]; } List<SqlExpression> expandedArgs = new List<SqlExpression>(); for(int i = 0; i < mcs[0].Arguments.Count; ++i) { List<SqlExpression> args = new List<SqlExpression>(); for(int j = 0; j < mcs.Length; ++j) { args.Add(mcs[j].Arguments[i]); } SqlExpression expanded = this.ExpandTogether(args); expandedArgs.Add(expanded); } return factory.MethodCall(mcs[0].Method, mcs[0].Object, expandedArgs.ToArray(), mcs[0].SourceExpression); } case SqlNodeType.ClientCase: { // Are they all the same? SqlClientCase[] scs = new SqlClientCase[exprs.Count]; scs[0] = (SqlClientCase)exprs[0]; for(int i = 1; i < scs.Length; ++i) { scs[i] = (SqlClientCase)exprs[i]; } // Expand expressions together. List<SqlExpression> expressions = new List<SqlExpression>(); for(int i = 0; i < scs.Length; ++i) { expressions.Add(scs[i].Expression); } SqlExpression expression = this.ExpandTogether(expressions); // Expand individual expressions together. List<SqlClientWhen> whens = new List<SqlClientWhen>(); for(int i = 0; i < scs[0].Whens.Count; ++i) { List<SqlExpression> scos = new List<SqlExpression>(); for(int j = 0; j < scs.Length; ++j) { SqlClientWhen when = scs[j].Whens[i]; scos.Add(when.Value); } whens.Add(new SqlClientWhen(scs[0].Whens[i].Match, this.ExpandTogether(scos))); } return new SqlClientCase(scs[0].ClrType, expression, whens, scs[0].SourceExpression); } case SqlNodeType.TypeCase: { // Are they all the same? SqlTypeCase[] tcs = new SqlTypeCase[exprs.Count]; tcs[0] = (SqlTypeCase)exprs[0]; for(int i = 1; i < tcs.Length; ++i) { tcs[i] = (SqlTypeCase)exprs[i]; } // Expand discriminators together. List<SqlExpression> discriminators = new List<SqlExpression>(); for(int i = 0; i < tcs.Length; ++i) { discriminators.Add(tcs[i].Discriminator); } SqlExpression discriminator = this.ExpandTogether(discriminators); // Write expanded discriminators back in. for(int i = 0; i < tcs.Length; ++i) { tcs[i].Discriminator = discriminators[i]; } // Expand individual type bindings together. List<SqlTypeCaseWhen> whens = new List<SqlTypeCaseWhen>(); for(int i = 0; i < tcs[0].Whens.Count; ++i) { List<SqlExpression> scos = new List<SqlExpression>(); for(int j = 0; j < tcs.Length; ++j) { SqlTypeCaseWhen when = tcs[j].Whens[i]; scos.Add(when.TypeBinding); } SqlExpression expanded = this.ExpandTogether(scos); whens.Add(new SqlTypeCaseWhen(tcs[0].Whens[i].Match, expanded)); } return factory.TypeCase(tcs[0].ClrType, tcs[0].RowType, discriminator, whens, tcs[0].SourceExpression); } case SqlNodeType.New: { // first verify all are similar client objects... SqlNew[] cobs = new SqlNew[exprs.Count]; cobs[0] = (SqlNew)exprs[0]; for(int i = 1, n = exprs.Count; i < n; i++) { if(exprs[i] == null || exprs[i].NodeType != SqlNodeType.New) throw Error.UnionIncompatibleConstruction(); cobs[i] = (SqlNew)exprs[1]; if(cobs[i].Members.Count != cobs[0].Members.Count) throw Error.UnionDifferentMembers(); for(int m = 0, mn = cobs[0].Members.Count; m < mn; m++) { if(cobs[i].Members[m].Member != cobs[0].Members[m].Member) { throw Error.UnionDifferentMemberOrder(); } } } SqlMemberAssign[] bindings = new SqlMemberAssign[cobs[0].Members.Count]; for(int m = 0, mn = bindings.Length; m < mn; m++) { List<SqlExpression> mexprs = new List<SqlExpression>(); for(int i = 0, n = exprs.Count; i < n; i++) { mexprs.Add(cobs[i].Members[m].Expression); } bindings[m] = new SqlMemberAssign(cobs[0].Members[m].Member, this.ExpandTogether(mexprs)); for(int i = 0, n = exprs.Count; i < n; i++) { cobs[i].Members[m].Expression = mexprs[i]; } } SqlExpression[] arguments = new SqlExpression[cobs[0].Args.Count]; for(int m = 0, mn = arguments.Length; m < mn; ++m) { List<SqlExpression> mexprs = new List<SqlExpression>(); for(int i = 0, n = exprs.Count; i < n; i++) { mexprs.Add(cobs[i].Args[m]); } arguments[m] = ExpandTogether(mexprs); } return factory.New(cobs[0].MetaType, cobs[0].Constructor, arguments, cobs[0].ArgMembers, bindings, exprs[0].SourceExpression); } case SqlNodeType.Link: { SqlLink[] links = new SqlLink[exprs.Count]; links[0] = (SqlLink)exprs[0]; for(int i = 1, n = exprs.Count; i < n; i++) { if(exprs[i] == null || exprs[i].NodeType != SqlNodeType.Link) throw Error.UnionIncompatibleConstruction(); links[i] = (SqlLink)exprs[i]; if(links[i].KeyExpressions.Count != links[0].KeyExpressions.Count || links[i].Member != links[0].Member || (links[i].Expansion != null) != (links[0].Expansion != null)) throw Error.UnionIncompatibleConstruction(); } SqlExpression[] kexprs = new SqlExpression[links[0].KeyExpressions.Count]; List<SqlExpression> lexprs = new List<SqlExpression>(); for(int k = 0, nk = links[0].KeyExpressions.Count; k < nk; k++) { lexprs.Clear(); for(int i = 0, n = exprs.Count; i < n; i++) { lexprs.Add(links[i].KeyExpressions[k]); } kexprs[k] = this.ExpandTogether(lexprs); for(int i = 0, n = exprs.Count; i < n; i++) { links[i].KeyExpressions[k] = lexprs[i]; } } SqlExpression expansion = null; if(links[0].Expansion != null) { lexprs.Clear(); for(int i = 0, n = exprs.Count; i < n; i++) { lexprs.Add(links[i].Expansion); } expansion = this.ExpandTogether(lexprs); for(int i = 0, n = exprs.Count; i < n; i++) { links[i].Expansion = lexprs[i]; } } return new SqlLink(links[0].Id, links[0].RowType, links[0].ClrType, links[0].SqlType, links[0].Expression, links[0].Member, kexprs, expansion, links[0].SourceExpression); } case SqlNodeType.Value: { /* * ExprSet of all literals of the same value reduce to just a single literal. */ SqlValue val0 = (SqlValue)exprs[0]; for(int i = 1; i < exprs.Count; ++i) { SqlValue val = (SqlValue)exprs[i]; if(!Equals(val.Value, val0.Value)) return this.ExpandIntoExprSet(exprs); } return val0; } case SqlNodeType.OptionalValue: { if(exprs[0].SqlType.CanBeColumn) { goto default; } List<SqlExpression> hvals = new List<SqlExpression>(exprs.Count); List<SqlExpression> vals = new List<SqlExpression>(exprs.Count); for(int i = 0, n = exprs.Count; i < n; i++) { if(exprs[i] == null || exprs[i].NodeType != SqlNodeType.OptionalValue) { throw Error.UnionIncompatibleConstruction(); } SqlOptionalValue sov = (SqlOptionalValue)exprs[i]; hvals.Add(sov.HasValue); vals.Add(sov.Value); } return new SqlOptionalValue(this.ExpandTogether(hvals), this.ExpandTogether(vals)); } case SqlNodeType.OuterJoinedValue: { if(exprs[0].SqlType.CanBeColumn) { goto default; } List<SqlExpression> values = new List<SqlExpression>(exprs.Count); for(int i = 0, n = exprs.Count; i < n; i++) { if(exprs[i] == null || exprs[i].NodeType != SqlNodeType.OuterJoinedValue) { throw Error.UnionIncompatibleConstruction(); } SqlUnary su = (SqlUnary)exprs[i]; values.Add(su.Operand); } return factory.Unary(SqlNodeType.OuterJoinedValue, this.ExpandTogether(values)); } case SqlNodeType.DiscriminatedType: { SqlDiscriminatedType sdt0 = (SqlDiscriminatedType)exprs[0]; List<SqlExpression> foos = new List<SqlExpression>(exprs.Count); foos.Add(sdt0.Discriminator); for(int i = 1, n = exprs.Count; i < n; i++) { SqlDiscriminatedType sdtN = (SqlDiscriminatedType)exprs[i]; if(sdtN.TargetType != sdt0.TargetType) { throw Error.UnionIncompatibleConstruction(); } foos.Add(sdtN.Discriminator); } return factory.DiscriminatedType(this.ExpandTogether(foos), ((SqlDiscriminatedType)exprs[0]).TargetType); } case SqlNodeType.ClientQuery: case SqlNodeType.Multiset: case SqlNodeType.Element: case SqlNodeType.Grouping: throw Error.UnionWithHierarchy(); default: return this.ExpandIntoExprSet(exprs); } }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { if(!_isDebugMode) { throw Error.InvalidFormatNode("MethodCall"); } if(mc.Method.IsStatic) { _commandStringBuilder.Append(mc.Method.DeclaringType); } else { this.Visit(mc.Object); } _commandStringBuilder.Append("."); _commandStringBuilder.Append(mc.Method.Name); _commandStringBuilder.Append("("); for(int i = 0, n = mc.Arguments.Count; i < n; i++) { if(i > 0) _commandStringBuilder.Append(", "); this.Visit(mc.Arguments[i]); } _commandStringBuilder.Append(")"); return mc; }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { mc.Object = this.VisitExpression(mc.Object); Reflection.ParameterInfo[] pis = mc.Method.GetParameters(); for(int i = 0, n = mc.Arguments.Count; i < n; i++) { mc.Arguments[i] = this.VisitNamedExpression(mc.Arguments[i], pis[i].Name); } return mc; }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { mc.Object = this.VisitExpression(mc.Object); for(int i = 0, n = mc.Arguments.Count; i < n; i++) { mc.Arguments[i] = this.VisitExpression(mc.Arguments[i]); } if(mc.Method.IsStatic) { if(mc.Method.Name == "Equals" && mc.Arguments.Count == 2) { return sql.Binary(SqlNodeType.EQ2V, mc.Arguments[0], mc.Arguments[1], mc.Method); } if(mc.Method.DeclaringType == typeof(string) && mc.Method.Name == "Concat") { SqlClientArray arr = mc.Arguments[0] as SqlClientArray; List<SqlExpression> exprs = null; if(arr != null) { exprs = arr.Expressions; } else { exprs = mc.Arguments; } if(exprs.Count == 0) { return sql.ValueFromObject("", false, mc.SourceExpression); } SqlExpression sum; if(exprs[0].SqlType.IsString || exprs[0].SqlType.IsChar) { sum = exprs[0]; } else { sum = sql.ConvertTo(typeof(string), exprs[0]); } for(int i = 1; i < exprs.Count; i++) { if(exprs[i].SqlType.IsString || exprs[i].SqlType.IsChar) { sum = sql.Concat(sum, exprs[i]); } else { sum = sql.Concat(sum, sql.ConvertTo(typeof(string), exprs[i])); } } return sum; } if(IsVbIIF(mc)) { return TranslateVbIIF(mc); } switch(mc.Method.Name) { case "op_Equality": return sql.Binary(SqlNodeType.EQ, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_Inequality": return sql.Binary(SqlNodeType.NE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_LessThan": return sql.Binary(SqlNodeType.LT, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_LessThanOrEqual": return sql.Binary(SqlNodeType.LE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_GreaterThan": return sql.Binary(SqlNodeType.GT, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_GreaterThanOrEqual": return sql.Binary(SqlNodeType.GE, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_Multiply": return sql.Binary(SqlNodeType.Mul, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_Division": return sql.Binary(SqlNodeType.Div, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_Subtraction": return sql.Binary(SqlNodeType.Sub, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_Addition": return sql.Binary(SqlNodeType.Add, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_Modulus": return sql.Binary(SqlNodeType.Mod, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_BitwiseAnd": return sql.Binary(SqlNodeType.BitAnd, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_BitwiseOr": return sql.Binary(SqlNodeType.BitOr, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_ExclusiveOr": return sql.Binary(SqlNodeType.BitXor, mc.Arguments[0], mc.Arguments[1], mc.Method, mc.ClrType); case "op_UnaryNegation": return sql.Unary(SqlNodeType.Negate, mc.Arguments[0], mc.Method, mc.SourceExpression); case "op_OnesComplement": return sql.Unary(SqlNodeType.BitNot, mc.Arguments[0], mc.Method, mc.SourceExpression); case "op_False": return sql.Unary(SqlNodeType.Not, mc.Arguments[0], mc.Method, mc.SourceExpression); } } else { if(mc.Method.Name == "Equals" && mc.Arguments.Count == 1) { return sql.Binary(SqlNodeType.EQ, mc.Object, mc.Arguments[0]); } if(mc.Method.Name == "GetType" && mc.Arguments.Count == 0) { MetaType mt = TypeSource.GetSourceMetaType(mc.Object, this.model); if(mt.HasInheritance) { Type discriminatorType = mt.Discriminator.Type; SqlDiscriminatorOf discriminatorOf = new SqlDiscriminatorOf(mc.Object, discriminatorType, this.sql.TypeProvider.From(discriminatorType), mc.SourceExpression); return this.VisitExpression(sql.DiscriminatedType(discriminatorOf, mt)); } return this.VisitExpression(sql.StaticType(mt, mc.SourceExpression)); } } return mc; }
private static bool IsVbIIF(SqlMethodCall mc) { return mc.Method.IsStatic && (mc.Method.DeclaringType!=null) && mc.Method.DeclaringType.FullName == "Microsoft.VisualBasic.Interaction" && mc.Method.Name == "IIf"; }
private static MethodSupport GetDecimalMethodSupport(SqlMethodCall mc) { if(mc.Method.IsStatic) { if(mc.Arguments.Count == 2) { switch(mc.Method.Name) { case "Multiply": case "Divide": case "Subtract": case "Add": case "Remainder": case "Round": return MethodSupport.Method; } } else if(mc.Arguments.Count == 1) { switch(mc.Method.Name) { case "Negate": case "Floor": case "Truncate": case "Round": return MethodSupport.Method; default: if(mc.Method.Name.StartsWith("To", StringComparison.Ordinal)) { return MethodSupport.Method; } break; } } } return MethodSupport.None; }
private static MethodSupport GetConvertMethodSupport(SqlMethodCall mc) { if(mc.Method.IsStatic && mc.Method.DeclaringType == typeof(Convert) && mc.Arguments.Count == 1) { switch(mc.Method.Name) { case "ToBoolean": case "ToDecimal": case "ToByte": case "ToChar": case "ToDouble": case "ToInt16": case "ToInt32": case "ToInt64": case "ToSingle": case "ToString": return MethodSupport.Method; case "ToDateTime": if(mc.Arguments[0].ClrType == typeof(string) || mc.Arguments[0].ClrType == typeof(DateTime)) { return MethodSupport.Method; } else { return MethodSupport.MethodGroup; } } } return MethodSupport.None; }
private static MethodSupport GetTimeSpanMethodSupport(SqlMethodCall mc) { if(!mc.Method.IsStatic && mc.Method.DeclaringType == typeof(TimeSpan)) { switch(mc.Method.Name) { case "Add": case "Subtract": case "CompareTo": case "Duration": case "Negate": return MethodSupport.Method; } } return MethodSupport.None; }
private static MethodSupport GetDateTimeOffsetMethodSupport(SqlMethodCall mc) { if(!mc.Method.IsStatic && mc.Method.DeclaringType == typeof(DateTimeOffset)) { switch(mc.Method.Name) { case "CompareTo": case "AddTicks": case "AddMonths": case "AddYears": case "AddMilliseconds": case "AddSeconds": case "AddMinutes": case "AddHours": case "AddDays": return MethodSupport.Method; case "Add": if(mc.Arguments.Count == 1 && mc.Arguments[0].ClrType == typeof(TimeSpan)) { return MethodSupport.Method; } else { return MethodSupport.MethodGroup; } } } return MethodSupport.None; }
private SqlExpression TranslateVbLikeString(SqlMethodCall mc) { // these should be true per the method signature Debug.Assert(mc.Arguments.Count == 3); Debug.Assert(mc.Arguments[0].ClrType == typeof(string)); Debug.Assert(mc.Arguments[1].ClrType == typeof(string)); bool needsEscape = true; Expression source = mc.SourceExpression; SqlExpression pattern = mc.Arguments[1]; if(pattern.NodeType == SqlNodeType.Value) { string unescapedText = (string)((SqlValue)pattern).Value; string patternText = SqlHelpers.TranslateVBLikePattern(unescapedText, '~'); pattern = sql.ValueFromObject(patternText, typeof(string), true, source); needsEscape = unescapedText != patternText; } else if(pattern.NodeType == SqlNodeType.ClientParameter) { SqlClientParameter cp = (SqlClientParameter)pattern; pattern = new SqlClientParameter( cp.ClrType, cp.SqlType, Expression.Lambda( Expression.Call(typeof(SqlHelpers), "TranslateVBLikePattern", Type.EmptyTypes, cp.Accessor.Body, Expression.Constant('~')), cp.Accessor.Parameters[0] ), cp.SourceExpression ); } else { throw Error.NonConstantExpressionsNotSupportedFor("LIKE"); } SqlExpression escape = needsEscape ? sql.ValueFromObject("~", false, mc.SourceExpression) : null; return sql.Like(mc.Arguments[0], pattern, escape, source); }
private SqlExpression TranslateVbCompareString(SqlMethodCall mc) { if(mc.Arguments.Count >= 2) { return CreateComparison(mc.Arguments[0], mc.Arguments[1], mc.SourceExpression); } throw GetMethodSupportException(mc); }
private SqlExpression TranslateVbConversionMethod(SqlMethodCall mc) { Expression source = mc.SourceExpression; if(mc.Arguments.Count == 1) { SqlExpression expr = mc.Arguments[0]; Type targetType = null; switch(mc.Method.Name) { case "ToBoolean": targetType = typeof(bool); break; case "ToSByte": targetType = typeof(sbyte); break; case "ToByte": targetType = typeof(byte); break; case "ToChar": targetType = typeof(char); break; case "ToCharArrayRankOne": targetType = typeof(char[]); break; case "ToDate": targetType = typeof(DateTime); break; case "ToDecimal": targetType = typeof(decimal); break; case "ToDouble": targetType = typeof(double); break; case "ToInteger": targetType = typeof(Int32); break; case "ToUInteger": targetType = typeof(UInt32); break; case "ToLong": targetType = typeof(Int64); break; case "ToULong": targetType = typeof(UInt64); break; case "ToShort": targetType = typeof(Int16); break; case "ToUShort": targetType = typeof(UInt16); break; case "ToSingle": targetType = typeof(float); break; case "ToString": targetType = typeof(string); break; } if(targetType != null) { if((targetType == typeof(int) || targetType == typeof(Single)) && expr.ClrType == typeof(bool)) { List<SqlExpression> matchesList = new List<SqlExpression>(); List<SqlExpression> valuesList = new List<SqlExpression>(); matchesList.Add(sql.ValueFromObject(true, false, source)); valuesList.Add(sql.ValueFromObject(-1, false, source)); matchesList.Add(sql.ValueFromObject(false, false, source)); valuesList.Add(sql.ValueFromObject(0, false, source)); return sql.Case(targetType, expr, matchesList, valuesList, source); } else if(mc.ClrType != mc.Arguments[0].ClrType) { // do the conversions that would be done for a cast "(<targetType>) expression" return sql.ConvertTo(targetType, expr); } else { return mc.Arguments[0]; } } } throw GetMethodSupportException(mc); }
private static bool IsVbCompareString(SqlMethodCall call) { return call.Method.IsStatic && (call.Method.DeclaringType!=null) && call.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && call.Method.Name == "CompareString"; }
private static bool IsSupportedVbHelperMethod(SqlMethodCall mc) { return IsVbIIF(mc); }
private static MethodSupport GetStringMethodSupport(SqlMethodCall mc) { if(mc.Method.DeclaringType == typeof(string)) { if(mc.Method.IsStatic) { if(mc.Method.Name == "Concat") { return MethodSupport.Method; } } else { switch(mc.Method.Name) { case "Contains": case "StartsWith": case "EndsWith": if(mc.Arguments.Count == 1) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "IndexOf": case "LastIndexOf": if(mc.Arguments.Count == 1 || mc.Arguments.Count == 2 || mc.Arguments.Count == 3) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "Insert": if(mc.Arguments.Count == 2) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "PadLeft": case "PadRight": case "Remove": case "Substring": if(mc.Arguments.Count == 1 || mc.Arguments.Count == 2) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "Replace": return MethodSupport.Method; case "Trim": case "ToLower": case "ToUpper": if(mc.Arguments.Count == 0) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "get_Chars": case "CompareTo": if(mc.Arguments.Count == 1) { return MethodSupport.Method; } return MethodSupport.MethodGroup; } } } return MethodSupport.None; }
private static bool IsSupportedMethod(SqlMethodCall mc) { if(mc.Method.IsStatic) { switch(mc.Method.Name) { case "op_Equality": case "op_Inequality": case "op_LessThan": case "op_LessThanOrEqual": case "op_GreaterThan": case "op_GreaterThanOrEqual": case "op_Multiply": case "op_Division": case "op_Subtraction": case "op_Addition": case "op_Modulus": case "op_BitwiseAnd": case "op_BitwiseOr": case "op_ExclusiveOr": case "op_UnaryNegation": case "op_OnesComplement": case "op_False": return true; case "Equals": return mc.Arguments.Count == 2; case "Concat": return mc.Method.DeclaringType == typeof(string); } } else { return mc.Method.Name == "Equals" && mc.Arguments.Count == 1 || mc.Method.Name == "GetType" && mc.Arguments.Count == 0; } return false; }
private static MethodSupport GetMathMethodSupport(SqlMethodCall mc) { if(mc.Method.IsStatic && mc.Method.DeclaringType == typeof(Math)) { switch(mc.Method.Name) { case "Abs": case "Acos": case "Asin": case "Atan": case "Ceiling": case "Cos": case "Cosh": case "Exp": case "Floor": case "Log10": if(mc.Arguments.Count == 1) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "Log": if(mc.Arguments.Count == 1 || mc.Arguments.Count == 2) { return MethodSupport.Method; }; return MethodSupport.MethodGroup; case "Max": case "Min": case "Pow": case "Atan2": case "BigMul": if(mc.Arguments.Count == 2) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "Round": if(mc.Arguments[mc.Arguments.Count - 1].ClrType == typeof(MidpointRounding) && (mc.Arguments.Count == 2 || mc.Arguments.Count == 3)) { return MethodSupport.Method; } return MethodSupport.MethodGroup; case "Sign": case "Sin": case "Sinh": case "Sqrt": case "Tan": case "Tanh": case "Truncate": if(mc.Arguments.Count == 1) { return MethodSupport.Method; } return MethodSupport.MethodGroup; } } return MethodSupport.None; }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { mc.Object = this.FetchExpression(mc.Object); for (int i = 0, n = mc.Arguments.Count; i < n; i++) { mc.Arguments[i] = this.FetchExpression(mc.Arguments[i]); } return mc; }
private static MethodSupport GetVbHelperMethodSupport(SqlMethodCall mc) { if(IsVbConversionMethod(mc) || IsVbCompareString(mc) || IsVbLike(mc)) { return MethodSupport.Method; } return MethodSupport.None; }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { SqlExpression[] args = new SqlExpression[mc.Arguments.Count]; for(int i = 0, n = mc.Arguments.Count; i < n; i++) { args[i] = this.VisitExpression(mc.Arguments[i]); } return new SqlMethodCall(mc.ClrType, mc.SqlType, mc.Method, this.VisitExpression(mc.Object), args, mc.SourceExpression); }
private static bool IsVbLike(SqlMethodCall mc) { return mc.Method.IsStatic && (mc.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.LikeOperator" && mc.Method.Name == "LikeString") || (mc.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Operators" && mc.Method.Name == "LikeString"); }
private Type GenerateMethodCall(SqlMethodCall mc) { ParameterInfo[] pis = mc.Method.GetParameters(); if(mc.Object != null) { Type actualType = this.GenerateExpressionForType(mc.Object, mc.Object.ClrType); if(actualType.IsValueType) { LocalBuilder loc = gen.DeclareLocal(actualType); gen.Emit(OpCodes.Stloc, loc); gen.Emit(OpCodes.Ldloca, loc); } } for(int i = 0, n = mc.Arguments.Count; i < n; i++) { ParameterInfo pi = pis[i]; Type pType = pi.ParameterType; if(pType.IsByRef) { pType = pType.GetElementType(); this.GenerateExpressionForType(mc.Arguments[i], pType); LocalBuilder loc = gen.DeclareLocal(pType); gen.Emit(OpCodes.Stloc, loc); gen.Emit(OpCodes.Ldloca, loc); } else { this.GenerateExpressionForType(mc.Arguments[i], pType); } } OpCode callOpCode = GetMethodCallOpCode(mc.Method); if(mc.Object != null && TypeSystem.IsNullableType(mc.Object.ClrType) && callOpCode == OpCodes.Callvirt) { gen.Emit(OpCodes.Constrained, mc.Object.ClrType); } gen.Emit(callOpCode, mc.Method); return mc.Method.ReturnType; }
private static bool IsVbConversionMethod(SqlMethodCall mc) { if(mc.Method.IsStatic && mc.Method.DeclaringType.FullName == "Microsoft.VisualBasic.CompilerServices.Conversions") { switch(mc.Method.Name) { case "ToBoolean": case "ToSByte": case "ToByte": case "ToChar": case "ToCharArrayRankOne": case "ToDate": case "ToDecimal": case "ToDouble": case "ToInteger": case "ToUInteger": case "ToLong": case "ToULong": case "ToShort": case "ToUShort": case "ToSingle": case "ToString": return true; } } return false; }
private SqlExpression TranslateVbIIF(SqlMethodCall mc) { //Check to see if the types can be implicitly converted from one to another. if(mc.Arguments[1].ClrType == mc.Arguments[2].ClrType) { List<SqlWhen> whens = new List<SqlWhen>(1); whens.Add(new SqlWhen(mc.Arguments[0], mc.Arguments[1])); SqlExpression @else = mc.Arguments[2]; while(@else.NodeType == SqlNodeType.SearchedCase) { SqlSearchedCase sc = (SqlSearchedCase)@else; whens.AddRange(sc.Whens); @else = sc.Else; } return sql.SearchedCase(whens.ToArray(), @else, mc.SourceExpression); } throw Error.IifReturnTypesMustBeEqual(mc.Arguments[1].ClrType.Name, mc.Arguments[2].ClrType.Name); }
private static bool IsCompareMethod(SqlMethodCall call) { return call.Method.IsStatic && call.Method.Name == "Compare" && call.Arguments.Count > 1 && call.Method.ReturnType == typeof(int); }
internal override SqlExpression VisitMethodCall(SqlMethodCall mc) { // eventually we may support this type of stuff given the SQL CLR, but for now it is illegal throw Error.MethodHasNoSupportConversionToSql(mc.Method.Name); }
private static MethodSupport GetNullableMethodSupport(SqlMethodCall mc) { if(mc.Method.Name == "GetValueOrDefault" && TypeSystem.IsNullableType(mc.Object.ClrType)) { return MethodSupport.Method; } return MethodSupport.None; }