예제 #1
0
		internal SqlJoin(SqlJoinType type, SqlSource left, SqlSource right, SqlExpression cond, Expression sourceExpression)
			: base(SqlNodeType.Join, sourceExpression) {
			this.JoinType = type;
			this.Left = left;
			this.Right = right;
			this.Condition = cond;
			}
예제 #2
0
		internal SqlMemberAssign(MemberInfo member, SqlExpression expr)
			: base(SqlNodeType.MemberAssign, expr.SourceExpression) {
			if (member == null)
				throw Error.ArgumentNull("member");
			this.member = member;
			this.Expression = expr;
			}
예제 #3
0
		internal SqlUnary(SqlNodeType nt, Type clrType, ProviderType sqlType, SqlExpression expr, MethodInfo method, Expression sourceExpression)
			: base(nt, clrType, sqlType, sourceExpression) {
			switch (nt) {
				case SqlNodeType.Not:
				case SqlNodeType.Not2V:
				case SqlNodeType.Negate:
				case SqlNodeType.BitNot:
				case SqlNodeType.IsNull:
				case SqlNodeType.IsNotNull:
				case SqlNodeType.Count:
				case SqlNodeType.LongCount:
				case SqlNodeType.Max:
				case SqlNodeType.Min:
				case SqlNodeType.Sum:
				case SqlNodeType.Avg:
				case SqlNodeType.Stddev:
				case SqlNodeType.Convert:
				case SqlNodeType.ValueOf:
				case SqlNodeType.Treat:
				case SqlNodeType.OuterJoinedValue:
				case SqlNodeType.ClrLength:
					break;
				default:
					throw Error.UnexpectedNode(nt);
			}
			this.Operand = expr;
			this.method = method;
			}
예제 #4
0
		private void CheckJoinCondition(SqlExpression expr)
		{
			switch(expr.NodeType)
			{
				case SqlNodeType.And:
				{
					SqlBinary b = (SqlBinary)expr;
					CheckJoinCondition(b.Left);
					CheckJoinCondition(b.Right);
					break;
				}
				case SqlNodeType.EQ:
				case SqlNodeType.EQ2V:
				{
					SqlBinary b = (SqlBinary)expr;
					SqlColumnRef crLeft = b.Left as SqlColumnRef;
					SqlColumnRef crRight = b.Right as SqlColumnRef;
					if(crLeft != null && crRight != null)
					{
						SqlColumn cLeft = crLeft.GetRootColumn();
						SqlColumn cRight = crRight.GetRootColumn();
						this._map[cLeft] = cRight;
						this._map[cRight] = cLeft;
					}
					break;
				}
			}
		}
예제 #5
0
		internal SqlBinary(SqlNodeType nt, Type clrType, ProviderType sqlType, SqlExpression left, SqlExpression right, MethodInfo method)
			: base(nt, clrType, sqlType, right.SourceExpression) {
			switch (nt) {
				case SqlNodeType.Add:
				case SqlNodeType.Sub:
				case SqlNodeType.Mul:
				case SqlNodeType.Div:
				case SqlNodeType.Mod:
				case SqlNodeType.BitAnd:
				case SqlNodeType.BitOr:
				case SqlNodeType.BitXor:
				case SqlNodeType.And:
				case SqlNodeType.Or:
				case SqlNodeType.GE:
				case SqlNodeType.GT:
				case SqlNodeType.LE:
				case SqlNodeType.LT:
				case SqlNodeType.EQ:
				case SqlNodeType.NE:
				case SqlNodeType.EQ2V:
				case SqlNodeType.NE2V:
				case SqlNodeType.Concat:
				case SqlNodeType.Coalesce:
					break;
				default:
					throw Error.UnexpectedNode(nt);
			}
			this.Left = left;
			this.Right = right;
			this.method = method;
			}
예제 #6
0
		internal SqlGrouping(Type clrType, ProviderType sqlType, SqlExpression key, SqlExpression group, Expression sourceExpression)
			: base(SqlNodeType.Grouping, clrType, sqlType, sourceExpression) {
			if (key == null) throw Error.ArgumentNull("key");
			if (group == null) throw Error.ArgumentNull("group");
			this.key = key;
			this.group = group;
			}
예제 #7
0
		internal SqlWhen(SqlExpression match, SqlExpression value) {
			// 'match' may be null when this when represents the ELSE condition.
			if (value == null)
				throw Error.ArgumentNull("value");
			this.Match = match;
			this.Value = value;
		}
예제 #8
0
		internal override SqlExpression AddTimeSpan(SqlExpression dateTime, SqlExpression timeSpan, bool asNullable)
		{
			Debug.Assert(this.IsHighPrecisionDateTimeType(timeSpan));

			SqlExpression ns = FunctionCallDatePart("NANOSECOND", timeSpan);
			SqlExpression ms = FunctionCallDatePart("MILLISECOND", timeSpan);
			SqlExpression ss = FunctionCallDatePart("SECOND", timeSpan);
			SqlExpression mi = FunctionCallDatePart("MINUTE", timeSpan);
			SqlExpression hh = FunctionCallDatePart("HOUR", timeSpan);

			SqlExpression result = dateTime;
			if(this.IsHighPrecisionDateTimeType(dateTime))
			{
				result = FunctionCallDateAdd("NANOSECOND", ns, result, dateTime.SourceExpression, asNullable);
			}
			else
			{
				result = FunctionCallDateAdd("MILLISECOND", ms, result, dateTime.SourceExpression, asNullable);
			}
			result = FunctionCallDateAdd("SECOND", ss, result, dateTime.SourceExpression, asNullable);
			result = FunctionCallDateAdd("MINUTE", mi, result, dateTime.SourceExpression, asNullable);
			result = FunctionCallDateAdd("HOUR", hh, result, dateTime.SourceExpression, asNullable);

			if(this.IsDateTimeOffsetType(dateTime))
				return ConvertTo(typeof(DateTimeOffset), result);

			return result;
		}
예제 #9
0
		internal SqlUserQuery(string queryText, SqlExpression projection, IEnumerable<SqlExpression> args, Expression source)
			: base(SqlNodeType.UserQuery, source) {
			this.queryText = queryText;
			this.Projection = projection;
			this.args = (args != null) ? new List<SqlExpression>(args) : new List<SqlExpression>();
			this.columns = new List<SqlUserColumn>();
			}
예제 #10
0
            internal override SqlNode Visit(SqlNode node) {
                if (node == null)
                    return null;

                sourceExpression = node as SqlExpression;
                if (sourceExpression != null) {
                    Type type = sourceExpression.ClrType;
                    UnwrapStack unwrap = this.UnwrapSequences;
                    while (unwrap != null) {
                        if (unwrap.Unwrap) {
                            type = TypeSystem.GetElementType(type);
                        }
                        unwrap = unwrap.Last;
                    }
                    sourceType = type;
                }
                if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType) {
                    return node; // Value types can't also have a dynamic type.
                }
                if (sourceType != null && TypeSystem.HasIEnumerable(sourceType)) {
                    return node; // Sequences can't be polymorphic.
                }

                switch (node.NodeType) {
                    case SqlNodeType.ScalarSubSelect:
                    case SqlNodeType.Multiset:
                    case SqlNodeType.Element:
                    case SqlNodeType.SearchedCase:
                    case SqlNodeType.ClientCase:
                    case SqlNodeType.SimpleCase:
                    case SqlNodeType.Member:
                    case SqlNodeType.DiscriminatedType:
                    case SqlNodeType.New:
                    case SqlNodeType.FunctionCall:
                    case SqlNodeType.MethodCall:
                    case SqlNodeType.Convert: // Object identity does not survive convert. It does survive Cast.
                        // Dig no further.
                        return node;
                    case SqlNodeType.TypeCase:
                        sourceType = ((SqlTypeCase)node).RowType.Type;
                        return node;
                    case SqlNodeType.Link:
                        sourceType = ((SqlLink)node).RowType.Type;
                        return node;
                    case SqlNodeType.Table:
                        sourceType = ((SqlTable)node).RowType.Type;
                        return node;
                    case SqlNodeType.Value:
                        SqlValue val = (SqlValue)node;
                        if (val.Value != null) {
                            // In some cases the ClrType of a Value node may
                            // differ from the actual runtime type of the value.
                            // Therefore, we ensure here that the correct type is set.
                            sourceType = val.Value.GetType();
                        }
                        return node;
                }
                return base.Visit(node);
            }
예제 #11
0
			private SqlValue GetLiteralValue(SqlExpression expr)
			{
				while(expr != null && expr.NodeType == SqlNodeType.ColumnRef)
				{
					expr = ((SqlColumnRef)expr).Column.Expression;
				}
				return expr as SqlValue;
			}
		internal void AddFactory(Type elementType, Type dataReaderType, object mapping, DataLoadOptions options, SqlExpression projection, IObjectReaderFactory factory)
		{
			this.list.AddFirst(new LinkedListNode<CacheInfo>(new CacheInfo(elementType, dataReaderType, mapping, options, projection, factory)));
			if(this.list.Count > this.maxCacheSize)
			{
				this.list.RemoveLast();
			}
		}
			public CacheInfo(Type elementType, Type dataReaderType, object mapping, DataLoadOptions options, SqlExpression projection, IObjectReaderFactory factory)
			{
				this.elementType = elementType;
				this.dataReaderType = dataReaderType;
				this.options = options;
				this.mapping = mapping;
				this.projection = projection;
				this.factory = factory;
			}
예제 #14
0
		internal SqlClientCase(Type clrType, SqlExpression expr, IEnumerable<SqlClientWhen> whens, Expression sourceExpression)
			: base(SqlNodeType.ClientCase, clrType, sourceExpression) {
			this.Expression = expr;
			if (whens == null)
				throw Error.ArgumentNull("whens");
			this.whens.AddRange(whens);
			if (this.whens.Count == 0)
				throw Error.ArgumentOutOfRange("whens");
			}
예제 #15
0
		internal SqlSelect(SqlExpression selection, SqlSource from, Expression sourceExpression)
			: base(SqlNodeType.Select, sourceExpression) {
			this.Row = new SqlRow(sourceExpression);
			this.Selection = selection;
			this.From = from;
			this.groupBy = new List<SqlExpression>();
			this.orderBy = new List<SqlOrderExpression>();
			this.orderingType = SqlOrderingType.Default;
			}
예제 #16
0
		internal SqlSearchedCase(Type clrType, IEnumerable<SqlWhen> whens, SqlExpression @else, Expression sourceExpression)
			: base(SqlNodeType.SearchedCase, clrType, sourceExpression)
		{
			if(whens == null)
				throw Error.ArgumentNull("whens");
			this.whens = new List<SqlWhen>(whens);
			if(this.whens.Count == 0)
				throw Error.ArgumentOutOfRange("whens");
			this.Else = @else;
		}
예제 #17
0
		internal SqlMethodCall(Type clrType, ProviderType sqlType, MethodInfo method, SqlExpression obj, IEnumerable<SqlExpression> args, Expression sourceExpression)
			: base(SqlNodeType.MethodCall, clrType, sqlType, sourceExpression) {
			if (method == null)
				throw Error.ArgumentNull("method");
			this.method = method;
			this.Object = obj;
			this.arguments = new List<SqlExpression>();
			if (args != null)
				this.arguments.AddRange(args);
			}
예제 #18
0
		internal SqlLike(Type clrType, ProviderType sqlType, SqlExpression expr, SqlExpression pattern, SqlExpression escape, Expression source)
			: base(SqlNodeType.Like, clrType, sqlType, source) {
			if (expr == null)
				throw Error.ArgumentNull("expr");
			if (pattern == null)
				throw Error.ArgumentNull("pattern");
			this.Expression = expr;
			this.Pattern = pattern;
			this.Escape = escape;
			}
예제 #19
0
		private SqlColumnRef MakeFlattenedColumn(SqlExpression expr, string name)
		{
			SqlColumn c = (!this.isInput) ? this.FindColumnWithExpression(this.row.Columns, expr) : null;
			if(c == null)
			{
				c = new SqlColumn(expr.ClrType, expr.SqlType, name, null, expr, expr.SourceExpression);
				this.row.Columns.Add(c);
			}
			return new SqlColumnRef(c);
		}
예제 #20
0
		internal SqlDiscriminatedType(ProviderType sqlType, SqlExpression discriminator, MetaType targetType, Expression sourceExpression)
			: base(SqlNodeType.DiscriminatedType,
				typeof(Type),
				sourceExpression) {
			if (discriminator == null)
				throw Error.ArgumentNull("discriminator");
			this.discriminator = discriminator;
			this.targetType = targetType;
			this.sqlType = sqlType;
				}
예제 #21
0
		internal override SqlNode VisitLink(SqlLink link)
		{
			SqlExpression expansion = this.VisitExpression(link.Expansion);
			SqlExpression[] exprs = new SqlExpression[link.KeyExpressions.Count];
			for(int i = 0, n = exprs.Length; i < n; i++)
			{
				exprs[i] = this.VisitExpression(link.KeyExpressions[i]);
			}
			return new SqlLink(link.Id, link.RowType, link.ClrType, link.SqlType, link.Expression, link.Member, exprs, expansion, link.SourceExpression);
		}
예제 #22
0
		internal SqlTypeCase(Type clrType, ProviderType sqlType, MetaType rowType, SqlExpression discriminator, IEnumerable<SqlTypeCaseWhen> whens, Expression sourceExpression)
			: base(SqlNodeType.TypeCase, clrType, sourceExpression) {
			this.Discriminator = discriminator;
			if (whens == null)
				throw Error.ArgumentNull("whens");
			this.whens.AddRange(whens);
			if (this.whens.Count == 0)
				throw Error.ArgumentOutOfRange("whens");
			this.sqlType = sqlType;
			this.rowType = rowType;
			}
예제 #23
0
		internal SqlLink(object id, MetaType rowType, Type clrType, ProviderType sqlType, SqlExpression expression, MetaDataMember member, IEnumerable<SqlExpression> keyExpressions, SqlExpression expansion, Expression sourceExpression)
			: base(SqlNodeType.Link, clrType, sqlType, sourceExpression) {
			this.id = id;
			this.rowType = rowType;
			this.expansion = expansion;
			this.expression = expression;
			this.member = member;
			this.keyExpressions = new List<SqlExpression>();
			if (keyExpressions != null)
				this.keyExpressions.AddRange(keyExpressions);
			}
예제 #24
0
		private SqlExpression ExtractParameter(SqlExpression expr)
		{
			Type clrType = expr.ClrType;
			if(expr.ClrType.IsValueType && !TypeSystem.IsNullableType(expr.ClrType))
			{
				clrType = typeof(Nullable<>).MakeGenericType(expr.ClrType);
			}
			this.externals.Add(expr);
			SqlParameter sp = new SqlParameter(clrType, expr.SqlType, "@x" + (this.parameters.Count + 1), expr.SourceExpression);
			this.parameters.Add(sp);
			return sp;
		}
예제 #25
0
		internal override SqlNode VisitLink(SqlLink link)
		{
			// Don't visit the Expression/Expansion for this link.
			// Any additional external refs in these expressions
			// should be ignored
			SqlExpression[] exprs = new SqlExpression[link.KeyExpressions.Count];
			for(int i = 0, n = exprs.Length; i < n; i++)
			{
				exprs[i] = this.VisitExpression(link.KeyExpressions[i]);
			}
			return new SqlLink(new object(), link.RowType, link.ClrType, link.SqlType, null, link.Member, exprs, null, link.SourceExpression);
		}
예제 #26
0
		internal SqlColumn(Type clrType, ProviderType sqlType, string name, MetaDataMember member, SqlExpression expr, Expression sourceExpression)
			: base(SqlNodeType.Column, clrType, sourceExpression) {
			if (typeof(Type).IsAssignableFrom(clrType))
				throw Error.ArgumentWrongValue("clrType");
			this.Name = name;
			this.member = member;
			this.Expression = expr;
			this.Ordinal = -1;
			if (sqlType == null)
				throw Error.ArgumentNull("sqlType");
			this.sqlType = sqlType;
			System.Diagnostics.Debug.Assert(sqlType.CanBeColumn);
			}
예제 #27
0
			// returns CONVERT(VARCHAR/NVARCHAR/VARBINARY(MAX), expr) if provType is one of Text, NText or Image
			// otherwise just returns expr 
			// changed is true if CONVERT(...(MAX),...) was added
			private SqlExpression ConvertToMax(SqlExpression expr, out bool changed)
			{
				changed = false;
				if(!expr.SqlType.IsLargeType)
					return expr;
				ProviderType newType = sql.TypeProvider.GetBestLargeType(expr.SqlType);
				changed = true;
				if(expr.SqlType != newType)
				{
					return ConvertToMax(expr, newType);
				}
				changed = false;
				return expr;
			}
예제 #28
0
		internal override SqlExpression ConvertValueToPredicate(SqlExpression valueExpression)
		{
			// Transform the 'Bit' expression into a 'Predicate' by forming the 
			// following operation:
			//    OriginalExpr = 1
			// Yukon and later could also handle:
			//    OriginalExpr = 'true'
			// but Sql2000 does not support this.
			return new SqlBinary(SqlNodeType.EQ,
				valueExpression.ClrType, sql.TypeProvider.From(typeof(bool)),
				valueExpression,
				sql.Value(typeof(bool), valueExpression.SqlType, true, false, valueExpression.SourceExpression)
				);
		}
예제 #29
0
		internal void GenerateBody(ILGenerator generator, SqlExpression expression)
		{
			this.gen = generator;
			this.globals = new List<object>();
			this.namedColumns = new List<NamedColumn>();
			// prepare locDataReader
			this.locDataReader = generator.DeclareLocal(this.compiler.DataReaderType);
			generator.Emit(OpCodes.Ldarg_0);
			generator.Emit(OpCodes.Ldfld, this.compiler.ReaderField);
			generator.Emit(OpCodes.Stloc, this.locDataReader);

			this.GenerateExpressionForType(expression, this.elementType);

			generator.Emit(OpCodes.Ret);
		}
예제 #30
0
		/// <summary>
		/// Helper for VisitBinaryOperator. Builds the new case with distributed valueds.
		/// </summary>
		private SqlExpression DistributeOperatorIntoCase(SqlNodeType nt, SqlSimpleCase sc, SqlExpression expr)
		{
			if(nt != SqlNodeType.EQ && nt != SqlNodeType.NE && nt != SqlNodeType.EQ2V && nt != SqlNodeType.NE2V)
				throw Error.ArgumentOutOfRange("nt");
			object val = Eval(expr);
			List<SqlExpression> values = new List<SqlExpression>();
			List<SqlExpression> matches = new List<SqlExpression>();
			foreach(SqlWhen when in sc.Whens)
			{
				matches.Add(when.Match);
				object whenVal = Eval(when.Value);
				bool eq = when.Value.SqlType.AreValuesEqual(whenVal, val);
				values.Add(_sql.ValueFromObject((nt == SqlNodeType.EQ || nt == SqlNodeType.EQ2V) == eq, false, sc.SourceExpression));
			}
			return this.VisitExpression(_sql.Case(typeof(bool), sc.Expression, matches, values, sc.SourceExpression));
		}