internal override SqlExpression VisitClientArray(SqlClientArray scar) { SqlExpression[] exprs = new SqlExpression[scar.Expressions.Count]; for (int i = 0, n = exprs.Length; i < n; i++) { exprs[i] = this.VisitExpression(scar.Expressions[i]); } return(new SqlClientArray(scar.ClrType, scar.SqlType, exprs, scar.SourceExpression)); }
internal override SqlExpression VisitClientArray(SqlClientArray scar) { if (!this.isDebugMode) { throw Error.InvalidFormatNode("ClientArray"); } sb.Append("new []{"); for (int i = 0, n = scar.Expressions.Count; i < n; i++) { if (i > 0) sb.Append(", "); this.Visit(scar.Expressions[i]); } sb.Append("}"); return scar; }
internal virtual SqlExpression VisitClientArray(SqlClientArray scar) { for (int i = 0, n = scar.Expressions.Count; i < n; i++) { scar.Expressions[i] = this.VisitExpression(scar.Expressions[i]); } return scar; }
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); }
internal override SqlExpression VisitClientArray(SqlClientArray scar) { SqlExpression[] exprs = new SqlExpression[scar.Expressions.Count]; for (int i = 0, n = exprs.Length; i < n; i++) { exprs[i] = this.VisitExpression(scar.Expressions[i]); } return new SqlClientArray(scar.ClrType, scar.SqlType, exprs, scar.SourceExpression); }
private SqlNode VisitInvocation(InvocationExpression invoke) { LambdaExpression lambda = (invoke.Expression.NodeType == ExpressionType.Quote) ? (LambdaExpression)((UnaryExpression)invoke.Expression).Operand : (invoke.Expression as LambdaExpression); if (lambda != null) { // just map arg values into lambda's parameters and evaluate lambda's body for (int i = 0, n = invoke.Arguments.Count; i < n; i++) { this.exprMap[lambda.Parameters[i]] = invoke.Arguments[i]; } return this.VisitInner(lambda.Body); } else { // check for compiled query invocation SqlExpression expr = this.VisitExpression(invoke.Expression); if (expr.NodeType == SqlNodeType.Value) { SqlValue value = (SqlValue)expr; Delegate d = value.Value as Delegate; if (d != null) { CompiledQuery cq = d.Target as CompiledQuery; if (cq != null) { return this.VisitInvocation(Expression.Invoke(cq.Expression, invoke.Arguments)); } else if (invoke.Arguments.Count == 0) { object invokeResult; try { invokeResult = d.DynamicInvoke(null); } catch (System.Reflection.TargetInvocationException e) { throw e.InnerException; } return this.sql.ValueFromObject(invokeResult, invoke.Type, true, this.dominatingExpression); } } } SqlExpression [] args = new SqlExpression[invoke.Arguments.Count]; for(int i = 0; i<args.Length; ++i) { args[i] = (SqlExpression)this.Visit(invoke.Arguments[i]); } var sca = new SqlClientArray(typeof(object[]), this.typeProvider.From(typeof(object[])), args, this.dominatingExpression); return sql.MethodCall(invoke.Type, typeof(Delegate).GetMethod("DynamicInvoke"), expr, new SqlExpression[] {sca}, this.dominatingExpression); } }
internal static bool CanBeCompared(SqlExpression node) { if (node == null) { return(true); } switch (node.NodeType) { case SqlNodeType.New: { SqlNew new1 = (SqlNew)node; for (int i = 0, n = new1.Args.Count; i < n; i++) { if (!CanBeCompared(new1.Args[i])) { return(false); } } for (int i = 0, n = new1.Members.Count; i < n; i++) { if (!CanBeCompared(new1.Members[i].Expression)) { return(false); } } return(true); } case SqlNodeType.ColumnRef: case SqlNodeType.Value: case SqlNodeType.UserColumn: return(true); case SqlNodeType.Link: { SqlLink l1 = (SqlLink)node; for (int i = 0, c = l1.KeyExpressions.Count; i < c; ++i) { if (!CanBeCompared(l1.KeyExpressions[i])) { return(false); } } return(true); } case SqlNodeType.OptionalValue: return(CanBeCompared(((SqlOptionalValue)node).Value)); case SqlNodeType.ValueOf: case SqlNodeType.OuterJoinedValue: return(CanBeCompared(((SqlUnary)node).Operand)); case SqlNodeType.Lift: return(CanBeCompared(((SqlLift)node).Expression)); case SqlNodeType.Grouping: { SqlGrouping g1 = (SqlGrouping)node; return(CanBeCompared(g1.Key) && CanBeCompared(g1.Group)); } case SqlNodeType.ClientArray: { if (node.SourceExpression.NodeType != ExpressionType.NewArrayInit && node.SourceExpression.NodeType != ExpressionType.NewArrayBounds) { return(false); } SqlClientArray a1 = (SqlClientArray)node; for (int i = 0, n = a1.Expressions.Count; i < n; i++) { if (!CanBeCompared(a1.Expressions[i])) { return(false); } } return(true); } case SqlNodeType.ClientCase: { SqlClientCase c1 = (SqlClientCase)node; for (int i = 0, n = c1.Whens.Count; i < n; i++) { if (!CanBeCompared(c1.Whens[i].Match) || !CanBeCompared(c1.Whens[i].Value)) { return(false); } } return(true); } case SqlNodeType.SearchedCase: { SqlSearchedCase c1 = (SqlSearchedCase)node; for (int i = 0, n = c1.Whens.Count; i < n; i++) { if (!CanBeCompared(c1.Whens[i].Match) || !CanBeCompared(c1.Whens[i].Value)) { return(false); } } return(CanBeCompared(c1.Else)); } case SqlNodeType.TypeCase: { SqlTypeCase c1 = (SqlTypeCase)node; if (!CanBeCompared(c1.Discriminator)) { return(false); } for (int i = 0, c = c1.Whens.Count; i < c; ++i) { if (!CanBeCompared(c1.Whens[i].Match)) { return(false); } if (!CanBeCompared(c1.Whens[i].TypeBinding)) { return(false); } } return(true); } case SqlNodeType.DiscriminatedType: return(CanBeCompared(((SqlDiscriminatedType)node).Discriminator)); case SqlNodeType.JoinedCollection: { SqlJoinedCollection j1 = (SqlJoinedCollection)node; return(CanBeCompared(j1.Count) && CanBeCompared(j1.Expression)); } case SqlNodeType.Member: return(CanBeCompared(((SqlMember)node).Expression)); case SqlNodeType.MethodCall: { SqlMethodCall mc = (SqlMethodCall)node; if (mc.Object != null && !CanBeCompared(mc.Object)) { return(false); } for (int i = 0, n = mc.Arguments.Count; i < n; i++) { if (!CanBeCompared(mc.Arguments[0])) { return(false); } } return(true); } case SqlNodeType.ClientQuery: return(true); case SqlNodeType.ClientParameter: default: return(false); } }
internal static bool AreSimilar(SqlExpression node1, SqlExpression node2) { if (node1 == node2) { return(true); } if (node1 == null || node2 == null) { return(false); } if (node1.NodeType != node2.NodeType || node1.ClrType != node2.ClrType || node1.SqlType != node2.SqlType) { return(false); } switch (node1.NodeType) { case SqlNodeType.New: { SqlNew new1 = (SqlNew)node1; SqlNew new2 = (SqlNew)node2; if (new1.Args.Count != new2.Args.Count || new1.Members.Count != new2.Members.Count) { return(false); } for (int i = 0, n = new1.Args.Count; i < n; i++) { if (!AreSimilar(new1.Args[i], new2.Args[i])) { return(false); } } for (int i = 0, n = new1.Members.Count; i < n; i++) { if (!MetaPosition.AreSameMember(new1.Members[i].Member, new2.Members[i].Member) || !AreSimilar(new1.Members[i].Expression, new2.Members[i].Expression)) { return(false); } } return(true); } case SqlNodeType.ColumnRef: { SqlColumnRef cref1 = (SqlColumnRef)node1; SqlColumnRef cref2 = (SqlColumnRef)node2; return(cref1.Column.Ordinal == cref2.Column.Ordinal); } case SqlNodeType.Link: { SqlLink l1 = (SqlLink)node1; SqlLink l2 = (SqlLink)node2; if (!MetaPosition.AreSameMember(l1.Member.Member, l2.Member.Member)) { return(false); } if (l1.KeyExpressions.Count != l2.KeyExpressions.Count) { return(false); } for (int i = 0, c = l1.KeyExpressions.Count; i < c; ++i) { if (!AreSimilar(l1.KeyExpressions[i], l2.KeyExpressions[i])) { return(false); } } return(true); } case SqlNodeType.Value: return(Object.Equals(((SqlValue)node1).Value, ((SqlValue)node2).Value)); case SqlNodeType.OptionalValue: { SqlOptionalValue ov1 = (SqlOptionalValue)node1; SqlOptionalValue ov2 = (SqlOptionalValue)node2; return(AreSimilar(ov1.Value, ov2.Value)); } case SqlNodeType.ValueOf: case SqlNodeType.OuterJoinedValue: return(AreSimilar(((SqlUnary)node1).Operand, ((SqlUnary)node2).Operand)); case SqlNodeType.Lift: return(AreSimilar(((SqlLift)node1).Expression, ((SqlLift)node2).Expression)); case SqlNodeType.Grouping: { SqlGrouping g1 = (SqlGrouping)node1; SqlGrouping g2 = (SqlGrouping)node2; return(AreSimilar(g1.Key, g2.Key) && AreSimilar(g1.Group, g2.Group)); } case SqlNodeType.ClientArray: { SqlClientArray a1 = (SqlClientArray)node1; SqlClientArray a2 = (SqlClientArray)node2; if (a1.Expressions.Count != a2.Expressions.Count) { return(false); } for (int i = 0, n = a1.Expressions.Count; i < n; i++) { if (!AreSimilar(a1.Expressions[i], a2.Expressions[i])) { return(false); } } return(true); } case SqlNodeType.UserColumn: return(((SqlUserColumn)node1).Name == ((SqlUserColumn)node2).Name); case SqlNodeType.ClientCase: { SqlClientCase c1 = (SqlClientCase)node1; SqlClientCase c2 = (SqlClientCase)node2; if (c1.Whens.Count != c2.Whens.Count) { return(false); } for (int i = 0, n = c1.Whens.Count; i < n; i++) { if (!AreSimilar(c1.Whens[i].Match, c2.Whens[i].Match) || !AreSimilar(c1.Whens[i].Value, c2.Whens[i].Value)) { return(false); } } return(true); } case SqlNodeType.SearchedCase: { SqlSearchedCase c1 = (SqlSearchedCase)node1; SqlSearchedCase c2 = (SqlSearchedCase)node2; if (c1.Whens.Count != c2.Whens.Count) { return(false); } for (int i = 0, n = c1.Whens.Count; i < n; i++) { if (!AreSimilar(c1.Whens[i].Match, c2.Whens[i].Match) || !AreSimilar(c1.Whens[i].Value, c2.Whens[i].Value)) { return(false); } } return(AreSimilar(c1.Else, c2.Else)); } case SqlNodeType.TypeCase: { SqlTypeCase c1 = (SqlTypeCase)node1; SqlTypeCase c2 = (SqlTypeCase)node2; if (!AreSimilar(c1.Discriminator, c2.Discriminator)) { return(false); } if (c1.Whens.Count != c2.Whens.Count) { return(false); } for (int i = 0, c = c1.Whens.Count; i < c; ++i) { if (!AreSimilar(c1.Whens[i].Match, c2.Whens[i].Match)) { return(false); } if (!AreSimilar(c1.Whens[i].TypeBinding, c2.Whens[i].TypeBinding)) { return(false); } } return(true); } case SqlNodeType.DiscriminatedType: { SqlDiscriminatedType dt1 = (SqlDiscriminatedType)node1; SqlDiscriminatedType dt2 = (SqlDiscriminatedType)node2; return(AreSimilar(dt1.Discriminator, dt2.Discriminator)); } case SqlNodeType.JoinedCollection: { SqlJoinedCollection j1 = (SqlJoinedCollection)node1; SqlJoinedCollection j2 = (SqlJoinedCollection)node2; return(AreSimilar(j1.Count, j2.Count) && AreSimilar(j1.Expression, j2.Expression)); } case SqlNodeType.Member: { SqlMember m1 = (SqlMember)node1; SqlMember m2 = (SqlMember)node2; return(m1.Member == m2.Member && AreSimilar(m1.Expression, m2.Expression)); } case SqlNodeType.ClientQuery: { SqlClientQuery cq1 = (SqlClientQuery)node1; SqlClientQuery cq2 = (SqlClientQuery)node2; if (cq1.Arguments.Count != cq2.Arguments.Count) { return(false); } for (int i = 0, n = cq1.Arguments.Count; i < n; i++) { if (!AreSimilar(cq1.Arguments[i], cq2.Arguments[i])) { return(false); } } return(true); } case SqlNodeType.MethodCall: { SqlMethodCall mc1 = (SqlMethodCall)node1; SqlMethodCall mc2 = (SqlMethodCall)node2; if (mc1.Method != mc2.Method || !AreSimilar(mc1.Object, mc2.Object)) { return(false); } if (mc1.Arguments.Count != mc2.Arguments.Count) { return(false); } for (int i = 0, n = mc1.Arguments.Count; i < n; i++) { if (!AreSimilar(mc1.Arguments[i], mc2.Arguments[i])) { return(false); } } return(true); } case SqlNodeType.ClientParameter: default: return(false); } }