コード例 #1
0
		internal override SqlExpression VisitTypeCase(SqlTypeCase tc) {
			tc.Discriminator = this.VisitExpression(tc.Discriminator);
			for (int i = 0, n = tc.Whens.Count; i < n; i++) {
				// Don't walk down the match side. This can't be a column.
				tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
			}
			return tc;
		}
コード例 #2
0
ファイル: SqlVisitor.cs プロジェクト: modulexcite/LinqToSQL2
 internal virtual SqlExpression VisitTypeCase(SqlTypeCase tc) {
     tc.Discriminator = this.VisitExpression(tc.Discriminator);
     for (int i = 0, n = tc.Whens.Count; i < n; i++) {
         SqlTypeCaseWhen when = tc.Whens[i];
         when.Match = this.VisitExpression(when.Match);
         when.TypeBinding = this.VisitExpression(when.TypeBinding);
     }
     return tc;
 }
コード例 #3
0
		private Type GenerateTypeCase(SqlTypeCase stc)
		{
			LocalBuilder locDiscriminator = gen.DeclareLocal(stc.Discriminator.ClrType);
			this.GenerateExpressionForType(stc.Discriminator, stc.Discriminator.ClrType);
			gen.Emit(OpCodes.Stloc, locDiscriminator);

			Label labNext = gen.DefineLabel();
			Label labEnd = gen.DefineLabel();
			bool hasDefault = false;

			for(int i = 0, n = stc.Whens.Count; i < n; i++)
			{
				if(i > 0)
				{
					gen.MarkLabel(labNext);
					labNext = gen.DefineLabel();
				}
				SqlTypeCaseWhen when = stc.Whens[i];
				if(when.Match != null)
				{
					gen.Emit(OpCodes.Ldloc, locDiscriminator);
					SqlValue vMatch = when.Match as SqlValue;
					Diagnostics.Debug.Assert(vMatch != null);
					this.GenerateConstant(locDiscriminator.LocalType, vMatch.Value);
					this.GenerateEquals(locDiscriminator.LocalType);
					gen.Emit(OpCodes.Brfalse, labNext);
				}
				else
				{
					Diagnostics.Debug.Assert(i == n - 1);
					hasDefault = true;
				}
				this.GenerateExpressionForType(when.TypeBinding, stc.ClrType);
				gen.Emit(OpCodes.Br, labEnd);
			}
			gen.MarkLabel(labNext);
			if(!hasDefault)
			{
				this.GenerateConstant(stc.ClrType, null);
			}
			gen.MarkLabel(labEnd);

			return stc.ClrType;
		}
コード例 #4
0
		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);
			}
		}
コード例 #5
0
		internal override SqlExpression VisitTypeCase(SqlTypeCase c)
		{
			if(!_isDebugMode)
			{
				throw Error.InvalidFormatNode("TypeCase");
			}
			_depth++;
			this.NewLine();
			_commandStringBuilder.Append("(CASE");
			_depth++;
			if(c.Discriminator != null)
			{
				_commandStringBuilder.Append(" ");
				this.Visit(c.Discriminator);
			}
			for(int i = 0, n = c.Whens.Count; i < n; i++)
			{
				SqlTypeCaseWhen when = c.Whens[i];
				if(i == n - 1 && when.Match == null)
				{
					this.NewLine();
					_commandStringBuilder.Append("ELSE ");
					this.Visit(when.TypeBinding);
				}
				else
				{
					this.NewLine();
					_commandStringBuilder.Append("WHEN ");
					this.Visit(when.Match);
					_commandStringBuilder.Append(" THEN ");
					this.Visit(when.TypeBinding);
				}
			}
			_depth--;
			this.NewLine();
			_commandStringBuilder.Append(" END)");
			_depth--;
			return c;
		}
コード例 #6
0
		internal override SqlExpression VisitTypeCase(SqlTypeCase tc)
		{
			SqlExpression disc = VisitExpression(tc.Discriminator);
			List<SqlTypeCaseWhen> whens = new List<SqlTypeCaseWhen>();
			foreach(SqlTypeCaseWhen when in tc.Whens)
			{
				whens.Add(new SqlTypeCaseWhen(VisitExpression(when.Match), VisitExpression(when.TypeBinding)));
			}
			return new SqlTypeCase(tc.ClrType, tc.SqlType, tc.RowType, disc, whens, tc.SourceExpression);
		}
コード例 #7
0
		internal override SqlExpression VisitTypeCase(SqlTypeCase tc)
		{
			bool saveCanJoin = this.canJoin;
			this.canJoin = false;
			try
			{
				return base.VisitTypeCase(tc);
			}
			finally
			{
				this.canJoin = saveCanJoin;
			}
		}
コード例 #8
0
			// currently only happens for generated test cases with optimization SimplifyCaseStatements off
			internal override SqlExpression VisitTypeCase(SqlTypeCase tc)
			{
				tc.Discriminator = base.VisitExpression(tc.Discriminator);
				List<SqlExpression> matches = new List<SqlExpression>();
				List<SqlExpression> values = new List<SqlExpression>();
				bool remainsTypeCase = true;
				foreach(SqlTypeCaseWhen when in tc.Whens)
				{
					SqlExpression newMatch = this.VisitExpression(when.Match);
					SqlExpression newNew = this.VisitExpression(when.TypeBinding);
					remainsTypeCase = remainsTypeCase && (newNew is SqlNew);
					matches.Add(newMatch);
					values.Add(newNew);
				}
				if(remainsTypeCase)
				{
					for(int i = 0, n = tc.Whens.Count; i < n; i++)
					{
						SqlTypeCaseWhen when = tc.Whens[i];
						when.Match = matches[i];
						when.TypeBinding = (SqlNew)values[i];
					}
					return tc;
				}
				else
				{
					return sql.Case(tc.ClrType, tc.Discriminator, matches, values, tc.SourceExpression);
				}
			}
コード例 #9
0
ファイル: Translator.cs プロジェクト: modulexcite/LinqToSQL2
 /// <summary>
 /// Find the alternative in type case that will best identify the object.
 /// If there is a SqlNew it is expected to have all the identity fields.
 /// If there is no SqlNew then we must be dealing with all literal NULL alternatives. In this case,
 /// just return the first one.
 /// </summary>
 private static SqlExpression BestIdentityNode(SqlTypeCase tc) {
     foreach (SqlTypeCaseWhen when in tc.Whens) {
         if (when.TypeBinding.NodeType == SqlNodeType.New) {
             return when.TypeBinding;
         }
     }
     return tc.Whens[0].TypeBinding; // There were no SqlNews, take the first alternative 
 }