internal override SqlExpression VisitNew(SqlNew sox) { if (sox.Constructor != null) { Reflection.ParameterInfo[] pis = sox.Constructor.GetParameters(); for (int i = 0, n = sox.Args.Count; i < n; i++) { sox.Args[i] = this.VisitNamedExpression(sox.Args[i], pis[i].Name); } } else { for (int i = 0, n = sox.Args.Count; i < n; i++) { sox.Args[i] = this.VisitExpression(sox.Args[i]); } } foreach (SqlMemberAssign ma in sox.Members) { string n = ma.Member.Name; if (this.useMappedNames) { n = sox.MetaType.GetDataMember(ma.Member).MappedName; } ma.Expression = this.VisitNamedExpression(ma.Expression, n); } return(sox); }
internal virtual SqlExpression VisitNew(SqlNew sox) { for (int i = 0, n = sox.Args.Count; i < n; i++) { sox.Args[i] = this.VisitExpression(sox.Args[i]); } for (int i = 0, n = sox.Members.Count; i < n; i++) { sox.Members[i].Expression = this.VisitExpression(sox.Members[i].Expression); } return sox; }
private static bool IsSupportedNew(SqlNew snew) { if (snew.ClrType == typeof(string)) { return IsSupportedStringNew(snew); } else if (snew.ClrType == typeof(TimeSpan)) { return IsSupportedTimeSpanNew(snew); } else if (snew.ClrType == typeof(DateTime)) { return IsSupportedDateTimeNew(snew); } return false; }
internal override SqlExpression VisitNew(SqlNew sox) { SqlExpression[] args = new SqlExpression[sox.Args.Count]; SqlMemberAssign[] bindings = new SqlMemberAssign[sox.Members.Count]; for (int i = 0, n = args.Length; i < n; i++) { args[i] = this.VisitExpression(sox.Args[i]); } for (int i = 0, n = bindings.Length; i < n; i++) { bindings[i] = this.VisitMemberAssign(sox.Members[i]); } return(new SqlNew(sox.MetaType, sox.SqlType, sox.Constructor, args, sox.ArgMembers, bindings, sox.SourceExpression)); }
internal override SqlExpression VisitNew(SqlNew sox) { // check the args for the PKs foreach (MemberInfo column in _identityMembers) { // assume we're invalid unless we find a matching argument which is // a bare column/columnRef to the PK bool isMatch = false; // find a matching arg foreach (SqlExpression expr in sox.Args) { isMatch = IsColumnMatch(column, expr); if (isMatch) { break; } } if (!isMatch) { foreach (SqlMemberAssign ma in sox.Members) { SqlExpression expr = ma.Expression; isMatch = IsColumnMatch(column, expr); if (isMatch) { break; } } } _isValid &= isMatch; if (!_isValid) { break; } } return(sox); }
internal SqlExpression BuildProjection(SqlExpression item, MetaType rowType, bool allowDeferred, SqlLink link, Expression source) { if (!rowType.HasInheritance) { return(this.BuildProjectionInternal(item, rowType, (rowType.Table != null) ? rowType.PersistentDataMembers : rowType.DataMembers, allowDeferred, link, source)); } else { // Build a type case that represents a switch between the various type. List <MetaType> mappedTypes = new List <MetaType>(rowType.InheritanceTypes); List <SqlTypeCaseWhen> whens = new List <SqlTypeCaseWhen>(); SqlTypeCaseWhen @else = null; MetaType root = rowType.InheritanceRoot; MetaDataMember discriminator = root.Discriminator; Type dt = discriminator.Type; SqlMember dm = sql.Member(item, discriminator.Member); foreach (MetaType type in mappedTypes) { if (type.HasInheritanceCode) { SqlNew defaultProjection = this.BuildProjectionInternal(item, type, type.PersistentDataMembers, allowDeferred, link, source); if (type.IsInheritanceDefault) { @else = new SqlTypeCaseWhen(null, defaultProjection); } // Add an explicit case even for the default. // Redundant results will be optimized out later. object code = InheritanceRules.InheritanceCodeForClientCompare(type.InheritanceCode, dm.SqlType); SqlExpression match = sql.Value(dt, sql.Default(discriminator), code, true, source); whens.Add(new SqlTypeCaseWhen(match, defaultProjection)); } } if (@else == null) { throw Error.EmptyCaseNotSupported(); } whens.Add(@else); // Add the else at the end. return(sql.TypeCase(root.Type, root, dm, whens.ToArray(), source)); } }
private static bool IsSupportedDateTimeNew(SqlNew sox) { if (sox.ClrType == typeof(DateTime) && sox.Args.Count >= 3 && sox.Args[0].ClrType == typeof(int) && sox.Args[1].ClrType == typeof(int) && sox.Args[2].ClrType == typeof(int)) { if (sox.Args.Count == 3) { return true; } if (sox.Args.Count >= 6 && sox.Args[3].ClrType == typeof(int) && sox.Args[4].ClrType == typeof(int) && sox.Args[5].ClrType == typeof(int)) { if (sox.Args.Count == 6) { return true; } if ((sox.Args.Count == 7) && (sox.Args[6].ClrType == typeof(int))) { return true; } } } return false; }
internal override SqlExpression VisitNew(SqlNew sox) { if (sox.Constructor != null) { System.Reflection.ParameterInfo[] pis = sox.Constructor.GetParameters(); for (int i = 0, n = sox.Args.Count; i < n; i++) { sox.Args[i] = this.VisitNamedExpression(sox.Args[i], pis[i].Name); } } else { for (int i = 0, n = sox.Args.Count; i < n; i++) { sox.Args[i] = this.VisitExpression(sox.Args[i]); } } foreach (SqlMemberAssign ma in sox.Members) { string n = ma.Member.Name; if (this.useMappedNames) { n = sox.MetaType.GetDataMember(ma.Member).MappedName; } ma.Expression = this.VisitNamedExpression(ma.Expression, n); } return sox; }
private static bool IsSupportedTimeSpanNew(SqlNew sox) { if (sox.Args.Count == 1) { return true; } else if (sox.Args.Count == 3) { return true; } else { if (sox.Args.Count == 4) { return true; } else if (sox.Args.Count == 5) { return true; } } return false; }
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 override SqlExpression VisitNew(SqlNew sox) { this.isNew = true; return base.VisitNew(sox); }
internal override SqlExpression VisitNew(SqlNew sox) { SqlExpression[] args = new SqlExpression[sox.Args.Count]; SqlMemberAssign[] bindings = new SqlMemberAssign[sox.Members.Count]; for (int i = 0, n = args.Length; i < n; i++) { args[i] = this.VisitExpression(sox.Args[i]); } for (int i = 0, n = bindings.Length; i < n; i++) { bindings[i] = this.VisitMemberAssign(sox.Members[i]); } return new SqlNew(sox.MetaType, sox.SqlType, sox.Constructor, args, sox.ArgMembers, bindings, sox.SourceExpression); }
internal override SqlExpression VisitNew(SqlNew sox) { for (int i = 0, n = sox.Args.Count; i < n; i++) { if (inGroupBy) { // we don't want to fetch expressions for group by, // since we want links to remain links so SqlFlattener // can deal with them properly sox.Args[i] = this.VisitExpression(sox.Args[i]); } else { sox.Args[i] = this.FetchExpression(sox.Args[i]); } } for (int i = 0, n = sox.Members.Count; i < n; i++) { SqlMemberAssign ma = sox.Members[i]; MetaDataMember mm = sox.MetaType.GetDataMember(ma.Member); MetaType otherType = mm.DeclaringType.InheritanceRoot; if (mm.IsAssociation && ma.Expression != null && ma.Expression.NodeType != SqlNodeType.Link && this.shape != null && this.shape.IsPreloaded(mm.Member) && mm.LoadMethod == null && this.alreadyIncluded != null && !this.alreadyIncluded.Contains(otherType)) { // The expression is already fetched, add it to the alreadyIncluded set. this.alreadyIncluded.Add(otherType); ma.Expression = this.VisitExpression(ma.Expression); this.alreadyIncluded.Remove(otherType); } else if (mm.IsAssociation || mm.IsDeferred) { ma.Expression = this.VisitExpression(ma.Expression); } else { ma.Expression = this.FetchExpression(ma.Expression); } } return sox; }
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 (!object.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); } }
private static bool IsSupportedStringNew(SqlNew snew) { return snew.Args.Count == 2 && snew.Args[0].ClrType == typeof(char) && snew.Args[1].ClrType == typeof(int); }
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 SqlNew New(MetaType type, ConstructorInfo cons, IEnumerable<SqlExpression> args, IEnumerable<MemberInfo> argMembers, IEnumerable<SqlMemberAssign> bindings, Expression sourceExpression) { SqlNew tb = new SqlNew(type, typeProvider.From(type.Type), cons, args, argMembers, bindings, sourceExpression); return tb; }
// transform constructors if necessary internal override SqlExpression VisitNew(SqlNew sox) { sox = (SqlNew)base.VisitNew(sox); if (sox.ClrType == typeof(string)) { return TranslateNewString(sox); } else if (sox.ClrType == typeof(TimeSpan)) { return TranslateNewTimeSpan(sox); } else if (sox.ClrType == typeof(DateTime)) { return TranslateNewDateTime(sox); } else if (sox.ClrType == typeof(DateTimeOffset)) { return TranslateNewDateTimeOffset(sox); } return sox; }
internal SqlNew New(MetaType type, ConstructorInfo cons, IEnumerable <SqlExpression> args, IEnumerable <MemberInfo> argMembers, IEnumerable <SqlMemberAssign> bindings, Expression sourceExpression) { SqlNew tb = new SqlNew(type, typeProvider.From(type.Type), cons, args, argMembers, bindings, sourceExpression); return(tb); }
private SqlExpression TranslateNewString(SqlNew sox) { // string(char c, int i) // --> REPLICATE(@c,@i) if (sox.ClrType == typeof(string) && sox.Args.Count == 2 && sox.Args[0].ClrType == typeof(char) && sox.Args[1].ClrType == typeof(int)) { return sql.FunctionCall(typeof(string), "REPLICATE", new SqlExpression[] { sox.Args[0], sox.Args[1] }, sox.SourceExpression); } throw Error.UnsupportedStringConstructorForm(); }
// // // // // internal override SqlExpression VisitNew(SqlNew sox) { // check the args for the PKs foreach (MemberInfo column in this.IdentityMembers) { // assume we're invalid unless we find a matching argument which is // a bare column/columnRef to the PK bool isMatch = false; // find a matching arg foreach (SqlExpression expr in sox.Args) { isMatch = IsColumnMatch(column, expr); if (isMatch) { break; } } if (!isMatch) { foreach (SqlMemberAssign ma in sox.Members) { SqlExpression expr = ma.Expression; isMatch = IsColumnMatch(column, expr); if (isMatch) { break; } } } this.IsValid &= isMatch; if (!this.IsValid) { break; } } return sox; }
private SqlExpression TranslateNewDateTime(SqlNew sox) { Expression source = sox.SourceExpression; // DateTime(int year, int month, int day) // --> CONVERT(DATETIME, CONVERT(nchar(2),@month) + '/' + CONVERT(nchar(2),@day) + '/' + CONVERT(nchar(4),@year),101) if (sox.ClrType == typeof(DateTime) && sox.Args.Count >= 3 && sox.Args[0].ClrType == typeof(int) && sox.Args[1].ClrType == typeof(int) && sox.Args[2].ClrType == typeof(int)) { SqlExpression char2 = sql.FunctionCall(typeof(void), "NCHAR", new SqlExpression[1] { sql.ValueFromObject(2, false, source) }, source); SqlExpression char4 = sql.FunctionCall(typeof(void), "NCHAR", new SqlExpression[1] { sql.ValueFromObject(4, false, source) }, source); SqlExpression year = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char4, sox.Args[0] }, source); SqlExpression month = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[1] }, source); SqlExpression day = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[2] }, source); SqlExpression datetime = new SqlVariable(typeof(void), null, "DATETIME", source); if (sox.Args.Count == 3) { SqlExpression date = sql.Concat(month, sql.ValueFromObject("/", false, source), day, sql.ValueFromObject("/", false, source), year); return sql.FunctionCall(typeof(DateTime), "CONVERT", new SqlExpression[3] { datetime, date, sql.ValueFromObject(101, false, source) }, source); } if (sox.Args.Count >= 6 && sox.Args[3].ClrType == typeof(int) && sox.Args[4].ClrType == typeof(int) && sox.Args[5].ClrType == typeof(int)) { // DateTime(year, month, day, hour, minute, second ) // --> CONVERT(DATETIME, CONVERT(nchar(2),@month) + '-' + CONVERT(nchar(2),@day) + '-' + CONVERT(nchar(4),@year) + // ' ' + CONVERT(nchar(2),@hour) + ':' + CONVERT(nchar(2),@minute) + ':' + CONVERT(nchar(2),@second) ,120) SqlExpression hour = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[3] }, source); SqlExpression minute = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[4] }, source); SqlExpression second = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[5] }, source); SqlExpression date = sql.Concat(year, sql.ValueFromObject("-", false, source), month, sql.ValueFromObject("-", false, source), day); SqlExpression time = sql.Concat(hour, sql.ValueFromObject(":", false, source), minute, sql.ValueFromObject(":", false, source), second); SqlExpression dateAndTime = sql.Concat(date, sql.ValueFromObject(' ', false, source), time); if (sox.Args.Count == 6) { return sql.FunctionCall(typeof(DateTime), "CONVERT", new SqlExpression[3] { datetime, dateAndTime, sql.ValueFromObject(120, false, source) }, source); } if ((sox.Args.Count == 7) && (sox.Args[6].ClrType == typeof(int))) { // DateTime(year, month, day, hour, minute, second, millisecond ) // add leading zeros to milliseconds by RIGHT(CONVERT(NCHAR(4),1000+@ms),3) SqlExpression msRaw = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] {char4, sql.Add(sql.ValueFromObject(1000, false, source),sox.Args[6])}, source); SqlExpression ms; if (this.providerMode == SqlProvider.ProviderMode.SqlCE) { //SqlCE doesn't have "RIGHT", so need to use "SUBSTRING" SqlExpression len = sql.FunctionCall(typeof(int), "LEN", new SqlExpression[1] { msRaw }, source); SqlExpression startIndex = sql.Binary(SqlNodeType.Sub, len, sql.ValueFromObject(2, false, source)); ms = sql.FunctionCall(typeof(string), "SUBSTRING", new SqlExpression[3] { msRaw, startIndex, sql.ValueFromObject(3, false, source) }, source); } else { ms = sql.FunctionCall(typeof(string), "RIGHT", new SqlExpression[2] { msRaw, sql.ValueFromObject(3, false, source) }, source); } dateAndTime = sql.Concat(dateAndTime, sql.ValueFromObject('.', false, source), ms); return sql.FunctionCall(typeof(DateTime), "CONVERT", new SqlExpression[3] { datetime, dateAndTime, sql.ValueFromObject(121, false, source) }, source); } } } throw Error.UnsupportedDateTimeConstructorForm(); }
internal override SqlExpression VisitNew(SqlNew sox) { this.isNew = true; return(base.VisitNew(sox)); }
private void FlattenGroupByExpression(List <SqlExpression> exprs, SqlExpression expr) { SqlNew sn = expr as SqlNew; if (sn != null) { foreach (SqlMemberAssign ma in sn.Members) { this.FlattenGroupByExpression(exprs, ma.Expression); } foreach (SqlExpression arg in sn.Args) { this.FlattenGroupByExpression(exprs, arg); } } else if (expr.NodeType == SqlNodeType.TypeCase) { SqlTypeCase tc = (SqlTypeCase)expr; this.FlattenGroupByExpression(exprs, tc.Discriminator); foreach (SqlTypeCaseWhen when in tc.Whens) { this.FlattenGroupByExpression(exprs, when.TypeBinding); } } else if (expr.NodeType == SqlNodeType.Link) { SqlLink link = (SqlLink)expr; if (link.Expansion != null) { this.FlattenGroupByExpression(exprs, link.Expansion); } else { foreach (SqlExpression key in link.KeyExpressions) { this.FlattenGroupByExpression(exprs, key); } } } else if (expr.NodeType == SqlNodeType.OptionalValue) { SqlOptionalValue sop = (SqlOptionalValue)expr; this.FlattenGroupByExpression(exprs, sop.HasValue); this.FlattenGroupByExpression(exprs, sop.Value); } else if (expr.NodeType == SqlNodeType.OuterJoinedValue) { this.FlattenGroupByExpression(exprs, ((SqlUnary)expr).Operand); } else if (expr.NodeType == SqlNodeType.DiscriminatedType) { SqlDiscriminatedType dt = (SqlDiscriminatedType)expr; this.FlattenGroupByExpression(exprs, dt.Discriminator); } else { // this expression should have been 'pushed-down' in SqlBinder, so we // should only find column-references & expr-sets unless the expression could not // be columnized (in which case it was a bad group-by expression.) if (expr.NodeType != SqlNodeType.ColumnRef && expr.NodeType != SqlNodeType.ExprSet) { if (!expr.SqlType.CanBeColumn) { throw Error.InvalidGroupByExpressionType(expr.SqlType.ToQueryString()); } throw Error.InvalidGroupByExpression(); } exprs.Add(expr); } }
private SqlExpression TranslateNewDateTimeOffset(SqlNew sox) { Expression source = sox.SourceExpression; if (sox.ClrType == typeof(DateTimeOffset)) { // DateTimeOffset(DateTime dateTime) // --> CONVERT(DATETIMEOFFSET, @dateTime) if (sox.Args.Count == 1 && sox.Args[0].ClrType == typeof(DateTime)) { return sql.FunctionCall(typeof(DateTimeOffset), "TODATETIMEOFFSET", new SqlExpression[2] { sox.Args[0], sql.ValueFromObject(0, false, source) }, source); } // DateTimeOffset(DateTime dateTime, TimeSpan timeSpan) // --> DATEADD(DATETIMEOFFSET, @dateTimePart) if (sox.Args.Count == 2 && sox.Args[0].ClrType == typeof(DateTime) && sox.Args[1].ClrType == typeof(TimeSpan)) { return sql.FunctionCall(typeof(DateTimeOffset), "TODATETIMEOFFSET", new SqlExpression[2] { sox.Args[0], sql.ConvertToInt(sql.ConvertToBigint(sql.Divide(sql.ConvertTimeToDouble(sox.Args[1]), TimeSpan.TicksPerMinute))) }, source); } // DateTimeOffset(year, month, day, hour, minute, second, [millisecond,] timeSpan) // if (sox.Args.Count >= 7 && sox.Args[0].ClrType == typeof(int) && sox.Args[1].ClrType == typeof(int) && sox.Args[2].ClrType == typeof(int) && sox.Args[3].ClrType == typeof(int) && sox.Args[4].ClrType == typeof(int) && sox.Args[5].ClrType == typeof(int)) { SqlExpression char2 = sql.FunctionCall(typeof(void), "NCHAR", new SqlExpression[1] { sql.ValueFromObject(2, false, source) }, source); SqlExpression char4 = sql.FunctionCall(typeof(void), "NCHAR", new SqlExpression[1] { sql.ValueFromObject(4, false, source) }, source); SqlExpression char5 = sql.FunctionCall(typeof(void), "NCHAR", new SqlExpression[1] { sql.ValueFromObject(5, false, source) }, source); // add leading zeros to year by RIGHT(CONVERT(NCHAR(5),10000+@ms),4) SqlExpression yyRaw = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] {char5, sql.Add(sql.ValueFromObject(10000, false, source),sox.Args[0])}, source); SqlExpression year = sql.FunctionCall(typeof(string), "RIGHT", new SqlExpression[2] { yyRaw, sql.ValueFromObject(4, false, source) }, source); SqlExpression month = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[1] }, source); SqlExpression day = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[2] }, source); SqlExpression hour = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[3] }, source); SqlExpression minute = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[4] }, source); SqlExpression second = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] { char2, sox.Args[5] }, source); SqlExpression date = sql.Concat(year, sql.ValueFromObject("-", false, source), month, sql.ValueFromObject("-", false, source), day); SqlExpression time = sql.Concat(hour, sql.ValueFromObject(":", false, source), minute, sql.ValueFromObject(":", false, source), second); SqlExpression datetimeoffset = new SqlVariable(typeof(void), null, "DATETIMEOFFSET", source); SqlExpression result, dateAndTime; int timeSpanIndex; if (sox.Args.Count == 7 && sox.Args[6].ClrType == typeof(TimeSpan)) { timeSpanIndex = 6; dateAndTime = sql.Concat(date, sql.ValueFromObject(' ', false, source), time); result = sql.FunctionCall(typeof(DateTimeOffset), "CONVERT", new SqlExpression[3] { datetimeoffset, dateAndTime, sql.ValueFromObject(120, false, source) }, source); } else if (sox.Args.Count == 8 && sox.Args[6].ClrType == typeof(int) && sox.Args[7].ClrType == typeof(TimeSpan)) { timeSpanIndex = 7; // add leading zeros to milliseconds by RIGHT(CONVERT(NCHAR(4),1000+@ms),3) SqlExpression msRaw = sql.FunctionCall(typeof(string), "CONVERT", new SqlExpression[2] {char4, sql.Add(sql.ValueFromObject(1000, false, source),sox.Args[6])}, source); SqlExpression ms = sql.FunctionCall(typeof(string), "RIGHT", new SqlExpression[2] { msRaw, sql.ValueFromObject(3, false, source) }, source); dateAndTime = sql.Concat(date, sql.ValueFromObject(' ', false, source), time, sql.ValueFromObject('.', false, source), ms); result = sql.FunctionCall(typeof(DateTimeOffset), "CONVERT", new SqlExpression[3] { datetimeoffset, dateAndTime, sql.ValueFromObject(121, false, source) }, source); } else { throw Error.UnsupportedDateTimeOffsetConstructorForm(); } return sql.FunctionCall(typeof(DateTimeOffset), "TODATETIMEOFFSET", new SqlExpression[2] { result, sql.ConvertToInt(sql.ConvertToBigint(sql.Divide(sql.ConvertTimeToDouble(sox.Args[timeSpanIndex]), TimeSpan.TicksPerMinute))) }, source); } } throw Error.UnsupportedDateTimeOffsetConstructorForm(); }
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); } }
internal override SqlExpression VisitNew(SqlNew sox) { if (!this.isDebugMode) { throw Error.InvalidFormatNode("New"); } sb.Append("new "); sb.Append(sox.ClrType.Name); sb.Append("{ "); // Visit Args for (int i = 0, n = sox.Args.Count; i < n; i++) { SqlExpression argExpr = sox.Args[i]; if (i > 0) sb.Append(", "); sb.Append(sox.ArgMembers[i].Name); sb.Append(" = "); this.Visit(argExpr); } // Visit Members for (int i = 0, n = sox.Members.Count; i < n; i++) { SqlMemberAssign ma = sox.Members[i]; if (i > 0) sb.Append(", "); string ename = this.InferName(ma.Expression, null); if (ename != ma.Member.Name) { sb.Append(ma.Member.Name); sb.Append(" = "); } this.Visit(ma.Expression); } sb.Append(" }"); return sox; }
private SqlExpression TranslateNewTimeSpan(SqlNew sox) { if (sox.Args.Count == 1) { return sql.ConvertTo(typeof(TimeSpan), sox.Args[0]); } else if (sox.Args.Count == 3) { // TimeSpan(hours, minutes, seconds) SqlExpression hours = sql.ConvertToBigint(sox.Args[0]); SqlExpression minutes = sql.ConvertToBigint(sox.Args[1]); SqlExpression seconds = sql.ConvertToBigint(sox.Args[2]); SqlExpression TicksFromHours = sql.Multiply(hours, TimeSpan.TicksPerHour); SqlExpression TicksFromMinutes = sql.Multiply(minutes, TimeSpan.TicksPerMinute); SqlExpression TicksFromSeconds = sql.Multiply(seconds, TimeSpan.TicksPerSecond); return sql.ConvertTo(typeof(TimeSpan), sql.Add(TicksFromHours, TicksFromMinutes, TicksFromSeconds)); } else { SqlExpression days = sql.ConvertToBigint(sox.Args[0]); SqlExpression hours = sql.ConvertToBigint(sox.Args[1]); SqlExpression minutes = sql.ConvertToBigint(sox.Args[2]); SqlExpression seconds = sql.ConvertToBigint(sox.Args[3]); SqlExpression TicksFromDays = sql.Multiply(days, TimeSpan.TicksPerDay); SqlExpression TicksFromHours = sql.Multiply(hours, TimeSpan.TicksPerHour); SqlExpression TicksFromMinutes = sql.Multiply(minutes, TimeSpan.TicksPerMinute); SqlExpression TicksFromSeconds = sql.Multiply(seconds, TimeSpan.TicksPerSecond); SqlExpression totalTicks = sql.Add(TicksFromDays, TicksFromHours, TicksFromMinutes, TicksFromSeconds); if (sox.Args.Count == 4) { // TimeSpan(days, hours, minutes, seconds) return sql.ConvertTo(typeof(TimeSpan), totalTicks); } else if (sox.Args.Count == 5) { // TimeSpan(days, hours, minutes, seconds, milliseconds) SqlExpression milliseconds = sql.ConvertToBigint(sox.Args[4]); SqlExpression ticksFromMs = sql.Multiply(milliseconds, TimeSpan.TicksPerMillisecond); return sql.ConvertTo(typeof(TimeSpan), sql.Add(totalTicks, ticksFromMs)); } } throw Error.UnsupportedTimeSpanConstructorForm(); }