internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { if (bo.NodeType == SqlNodeType.EQ || bo.NodeType == SqlNodeType.NE || bo.NodeType == SqlNodeType.EQ2V || bo.NodeType == SqlNodeType.NE2V || bo.NodeType == SqlNodeType.GT || bo.NodeType == SqlNodeType.GE || bo.NodeType == SqlNodeType.LT || bo.NodeType == SqlNodeType.LE) { if (!bo.Left.SqlType.SupportsComparison || !bo.Right.SqlType.SupportsComparison) { throw Error.UnhandledStringTypeComparison(); } } bo.Left = this.VisitExpression(bo.Left); bo.Right = this.VisitExpression(bo.Right); return(bo); }
internal override SqlSelect VisitSelect(SqlSelect select) { // DevDiv 179191 if (select.Where != null && select.Where.NodeType == SqlNodeType.Coalesce) { SqlBinary bin = (SqlBinary)select.Where; if (bin.Right.NodeType == SqlNodeType.Value) { SqlValue value = (SqlValue)bin.Right; if (value.Value != null && value.Value.GetType() == typeof(bool) && (bool)value.Value == false) { select.Where = bin.Left; } } } return(base.VisitSelect(select)); }
internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { // // Special case to allow DateTime CLR type to be passed as a paramater where // a SQL type TIME is expected. We do this only for the equality/inequality // comparisons. // switch (bo.NodeType) { case SqlNodeType.EQ: case SqlNodeType.EQ2V: case SqlNodeType.NE: case SqlNodeType.NE2V: { SqlDbType leftSqlDbType = ((SqlTypeSystem.SqlType)(bo.Left.SqlType)).SqlDbType; SqlDbType rightSqlDbType = ((SqlTypeSystem.SqlType)(bo.Right.SqlType)).SqlDbType; if (leftSqlDbType == rightSqlDbType) { break; } bool isLeftColRef = bo.Left is SqlColumnRef; bool isRightColRef = bo.Right is SqlColumnRef; if (isLeftColRef == isRightColRef) { break; } if (isLeftColRef && leftSqlDbType == SqlDbType.Time && bo.Right.ClrType == typeof(DateTime)) { this.timeProviderType = bo.Left.SqlType; } else if (isRightColRef && rightSqlDbType == SqlDbType.Time && bo.Left.ClrType == typeof(DateTime)) { this.timeProviderType = bo.Left.SqlType; } break; } } base.VisitBinaryOperator(bo); return(bo); }
internal static bool CanConvert(SqlNode node) { SqlBinary bo = node as SqlBinary; if (bo != null && (IsCompareToValue(bo) || IsVbCompareStringEqualsValue(bo))) { return(true); } SqlMember sm = node as SqlMember; if (sm != null && IsSupportedMember(sm)) { return(true); } SqlMethodCall mc = node as SqlMethodCall; if (mc != null && (IsSupportedMethod(mc) || IsSupportedVbHelperMethod(mc))) { return(true); } return(false); }
/// <summary> /// Replace equals and not equals: /// /// | CASE XXX | CASE XXX CASE XXX /// | WHEN AAA THEN MMMM | != RRRR ===> WHEN AAA THEN (MMMM != RRRR) ==> WHEN AAA THEN true /// | WHEN BBB THEN NNNN | WHEN BBB THEN (NNNN != RRRR) WHEN BBB THEN false /// | etc. | etc. etc. /// | ELSE OOOO | ELSE (OOOO != RRRR) ELSE true /// | END END END /// /// Where MMMM, NNNN and RRRR are constants. /// </summary> internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { switch (bo.NodeType) { case SqlNodeType.EQ: case SqlNodeType.NE: case SqlNodeType.EQ2V: case SqlNodeType.NE2V: if (bo.Left.NodeType == SqlNodeType.SimpleCase && bo.Right.NodeType == SqlNodeType.Value && AreCaseWhenValuesConstant((SqlSimpleCase)bo.Left)) { return(this.DistributeOperatorIntoCase(bo.NodeType, (SqlSimpleCase)bo.Left, bo.Right)); } else if (bo.Right.NodeType == SqlNodeType.SimpleCase && bo.Left.NodeType == SqlNodeType.Value && AreCaseWhenValuesConstant((SqlSimpleCase)bo.Right)) { return(this.DistributeOperatorIntoCase(bo.NodeType, (SqlSimpleCase)bo.Right, bo.Left)); } break; } return(base.VisitBinaryOperator(bo)); }
internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { base.VisitBinaryOperator(bo); if (bo.NodeType.IsComparisonOperator() && bo.Left.ClrType != typeof(bool) && bo.Right.ClrType != typeof(bool)) { // Strip unnecessary CONVERT calls. if (bo.Left.NodeType == SqlNodeType.Convert) { var conv = (SqlUnary)bo.Left; if (CanDbConvert(conv.Operand.ClrType, bo.Right.ClrType) && conv.Operand.SqlType.ComparePrecedenceTo(bo.Right.SqlType) != 1) { return(VisitBinaryOperator(new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, conv.Operand, bo.Right))); } } if (bo.Right.NodeType == SqlNodeType.Convert) { var conv = (SqlUnary)bo.Right; if (CanDbConvert(conv.Operand.ClrType, bo.Left.ClrType) && conv.Operand.SqlType.ComparePrecedenceTo(bo.Left.SqlType) != 1) { return(VisitBinaryOperator(new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, bo.Left, conv.Operand))); } } } if (bo.Right != null && bo.NodeType != SqlNodeType.Concat) { SqlExpression left = bo.Left; SqlExpression right = bo.Right; this.CoerceBinaryArgs(ref left, ref right); if (bo.Left != left || bo.Right != right) { bo = sql.Binary(bo.NodeType, left, right); } bo.SetSqlType(typeProvider.PredictTypeForBinary(bo.NodeType, left.SqlType, right.SqlType)); } if (bo.NodeType.IsComparisonOperator()) { // When comparing a unicode value against a non-unicode column, // we want retype the parameter as non-unicode. Func <SqlExpression, SqlExpression, bool> needsRetype = (expr, val) => (val.NodeType == SqlNodeType.Value || val.NodeType == SqlNodeType.ClientParameter) && !(expr.NodeType == SqlNodeType.Value || expr.NodeType == SqlNodeType.ClientParameter) && val.SqlType.IsUnicodeType && !expr.SqlType.IsUnicodeType; SqlSimpleTypeExpression valueToRetype = null; if (needsRetype(bo.Left, bo.Right)) { valueToRetype = (SqlSimpleTypeExpression)bo.Right; } else if (needsRetype(bo.Right, bo.Left)) { valueToRetype = (SqlSimpleTypeExpression)bo.Left; } if (valueToRetype != null) { valueToRetype.SetSqlType(valueToRetype.SqlType.GetNonUnicodeEquivalent()); } } return(bo); }
internal static bool?CanBeNull(SqlExpression expr) { switch (expr.NodeType) { case SqlNodeType.ExprSet: SqlExprSet exprSet = (SqlExprSet)expr; return(CanBeNull(exprSet.Expressions)); case SqlNodeType.SimpleCase: SqlSimpleCase sc = (SqlSimpleCase)expr; return(CanBeNull(sc.Whens.Select(w => w.Value))); case SqlNodeType.Column: SqlColumn col = (SqlColumn)expr; if (col.MetaMember != null) { return(col.MetaMember.CanBeNull); } else if (col.Expression != null) { return(CanBeNull(col.Expression)); } return(null); // Don't know. case SqlNodeType.ColumnRef: SqlColumnRef cref = (SqlColumnRef)expr; return(CanBeNull(cref.Column)); case SqlNodeType.Value: return(((SqlValue)expr).Value == null); case SqlNodeType.New: case SqlNodeType.Multiset: case SqlNodeType.Grouping: case SqlNodeType.DiscriminatedType: case SqlNodeType.IsNotNull: // IsNull\IsNotNull always return true or false and can never return NULL. case SqlNodeType.IsNull: case SqlNodeType.Exists: return(false); 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.Concat: { SqlBinary bop = (SqlBinary)expr; bool? left = CanBeNull(bop.Left); bool? right = CanBeNull(bop.Right); return((left != false) || (right != false)); } case SqlNodeType.Negate: case SqlNodeType.BitNot: { SqlUnary uop = (SqlUnary)expr; return(CanBeNull(uop.Operand)); } case SqlNodeType.Lift: { SqlLift lift = (SqlLift)expr; return(CanBeNull(lift.Expression)); } case SqlNodeType.OuterJoinedValue: return(true); default: return(null); // Don't know. } }
internal SqlExpression TranslateEquals(SqlBinary expr) { System.Diagnostics.Debug.Assert( expr.NodeType == SqlNodeType.EQ || expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V); SqlExpression eLeft = expr.Left; SqlExpression eRight = expr.Right; if (eRight.NodeType == SqlNodeType.Element) { SqlSubSelect sub = (SqlSubSelect)eRight; SqlAlias alias = new SqlAlias(sub.Select); SqlAliasRef aref = new SqlAliasRef(alias); SqlSelect select = new SqlSelect(aref, alias, expr.SourceExpression); select.Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(eLeft), aref); return(sql.SubSelect(SqlNodeType.Exists, select)); } else if (eLeft.NodeType == SqlNodeType.Element) { SqlSubSelect sub = (SqlSubSelect)eLeft; SqlAlias alias = new SqlAlias(sub.Select); SqlAliasRef aref = new SqlAliasRef(alias); SqlSelect select = new SqlSelect(aref, alias, expr.SourceExpression); select.Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(eRight), aref); return(sql.SubSelect(SqlNodeType.Exists, select)); } MetaType mtLeft = TypeSource.GetSourceMetaType(eLeft, this.services.Model); MetaType mtRight = TypeSource.GetSourceMetaType(eRight, this.services.Model); if (eLeft.NodeType == SqlNodeType.TypeCase) { eLeft = BestIdentityNode((SqlTypeCase)eLeft); } if (eRight.NodeType == SqlNodeType.TypeCase) { eRight = BestIdentityNode((SqlTypeCase)eRight); } if (mtLeft.IsEntity && mtRight.IsEntity && mtLeft.Table != mtRight.Table) { throw Error.CannotCompareItemsAssociatedWithDifferentTable(); } // do simple or no translation for non-structural types if (!mtLeft.IsEntity && !mtRight.IsEntity && (eLeft.NodeType != SqlNodeType.New || eLeft.SqlType.CanBeColumn) && (eRight.NodeType != SqlNodeType.New || eRight.SqlType.CanBeColumn)) { if (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) { return(this.TranslateEqualsOp(expr.NodeType, sql.DoNotVisitExpression(expr.Left), sql.DoNotVisitExpression(expr.Right), false)); } return(expr); } // If the two types are not comparable, we return the predicate "1=0". if ((mtLeft != mtRight) && (mtLeft.InheritanceRoot != mtRight.InheritanceRoot)) { return(sql.Binary(SqlNodeType.EQ, sql.ValueFromObject(0, expr.SourceExpression), sql.ValueFromObject(1, expr.SourceExpression))); } List <SqlExpression> exprs1; List <SqlExpression> exprs2; SqlLink link1 = eLeft as SqlLink; if (link1 != null && link1.Member.IsAssociation && link1.Member.Association.IsForeignKey) { exprs1 = link1.KeyExpressions; } else { exprs1 = this.GetIdentityExpressions(mtLeft, sql.DoNotVisitExpression(eLeft)); } SqlLink link2 = eRight as SqlLink; if (link2 != null && link2.Member.IsAssociation && link2.Member.Association.IsForeignKey) { exprs2 = link2.KeyExpressions; } else { exprs2 = this.GetIdentityExpressions(mtRight, sql.DoNotVisitExpression(eRight)); } System.Diagnostics.Debug.Assert(exprs1.Count > 0); System.Diagnostics.Debug.Assert(exprs2.Count > 0); System.Diagnostics.Debug.Assert(exprs1.Count == exprs2.Count); SqlExpression exp = null; SqlNodeType eqKind = (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) ? SqlNodeType.EQ2V : SqlNodeType.EQ; for (int i = 0, n = exprs1.Count; i < n; i++) { SqlExpression eq = this.TranslateEqualsOp(eqKind, exprs1[i], exprs2[i], !mtLeft.IsEntity); if (exp == null) { exp = eq; } else { exp = sql.Binary(SqlNodeType.And, exp, eq); } } if (expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.NE2V) { exp = sql.Unary(SqlNodeType.Not, exp, exp.SourceExpression); } return(exp); }
internal virtual SqlExpression VisitBinaryOperator(SqlBinary bo) { bo.Left = this.VisitExpression(bo.Left); bo.Right = this.VisitExpression(bo.Right); return(bo); }
internal static bool AreEqual(SqlNode node1, SqlNode node2) { if (node1 == node2) { return(true); } if (node1 == null || node2 == null) { return(false); } if (node1.NodeType == SqlNodeType.SimpleCase) { node1 = UnwrapTrivialCaseExpression((SqlSimpleCase)node1); } if (node2.NodeType == SqlNodeType.SimpleCase) { node2 = UnwrapTrivialCaseExpression((SqlSimpleCase)node2); } if (node1.NodeType != node2.NodeType) { // allow expression sets to compare against single expressions if (node1.NodeType == SqlNodeType.ExprSet) { SqlExprSet eset = (SqlExprSet)node1; for (int i = 0, n = eset.Expressions.Count; i < n; i++) { if (AreEqual(eset.Expressions[i], node2)) { return(true); } } } else if (node2.NodeType == SqlNodeType.ExprSet) { SqlExprSet eset = (SqlExprSet)node2; for (int i = 0, n = eset.Expressions.Count; i < n; i++) { if (AreEqual(node1, eset.Expressions[i])) { return(true); } } } return(false); } if (node1.Equals(node2)) { return(true); } switch (node1.NodeType) { case SqlNodeType.Not: case SqlNodeType.Not2V: case SqlNodeType.Negate: case SqlNodeType.BitNot: case SqlNodeType.IsNull: case SqlNodeType.IsNotNull: case SqlNodeType.Count: case SqlNodeType.Max: case SqlNodeType.Min: case SqlNodeType.Sum: case SqlNodeType.Avg: case SqlNodeType.Stddev: case SqlNodeType.ValueOf: case SqlNodeType.OuterJoinedValue: case SqlNodeType.ClrLength: return(AreEqual(((SqlUnary)node1).Operand, ((SqlUnary)node2).Operand)); 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: SqlBinary firstNode = (SqlBinary)node1; SqlBinary secondNode = (SqlBinary)node2; return(AreEqual(firstNode.Left, secondNode.Left) && AreEqual(firstNode.Right, secondNode.Right)); case SqlNodeType.Convert: case SqlNodeType.Treat: { SqlUnary sun1 = (SqlUnary)node1; SqlUnary sun2 = (SqlUnary)node2; return(sun1.ClrType == sun2.ClrType && sun1.SqlType == sun2.SqlType && AreEqual(sun1.Operand, sun2.Operand)); } case SqlNodeType.Between: { SqlBetween b1 = (SqlBetween)node1; SqlBetween b2 = (SqlBetween)node1; return(AreEqual(b1.Expression, b2.Expression) && AreEqual(b1.Start, b2.Start) && AreEqual(b1.End, b2.End)); } case SqlNodeType.Parameter: return(node1 == node2); case SqlNodeType.Alias: return(AreEqual(((SqlAlias)node1).Node, ((SqlAlias)node2).Node)); case SqlNodeType.AliasRef: return(AreEqual(((SqlAliasRef)node1).Alias, ((SqlAliasRef)node2).Alias)); case SqlNodeType.Column: SqlColumn col1 = (SqlColumn)node1; SqlColumn col2 = (SqlColumn)node2; return(col1 == col2 || (col1.Expression != null && col2.Expression != null && AreEqual(col1.Expression, col2.Expression))); case SqlNodeType.Table: return(((SqlTable)node1).MetaTable == ((SqlTable)node2).MetaTable); case SqlNodeType.Member: return((((SqlMember)node1).Member == ((SqlMember)node2).Member) && AreEqual(((SqlMember)node1).Expression, ((SqlMember)node2).Expression)); case SqlNodeType.ColumnRef: SqlColumnRef cref1 = (SqlColumnRef)node1; SqlColumnRef cref2 = (SqlColumnRef)node2; return(GetBaseColumn(cref1) == GetBaseColumn(cref2)); case SqlNodeType.Value: return(Object.Equals(((SqlValue)node1).Value, ((SqlValue)node2).Value)); case SqlNodeType.TypeCase: { SqlTypeCase c1 = (SqlTypeCase)node1; SqlTypeCase c2 = (SqlTypeCase)node2; if (!AreEqual(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 (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match)) { return(false); } if (!AreEqual(c1.Whens[i].TypeBinding, c2.Whens[i].TypeBinding)) { 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 (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match) || !AreEqual(c1.Whens[i].Value, c2.Whens[i].Value)) { return(false); } } return(AreEqual(c1.Else, c2.Else)); } 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 (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match) || !AreEqual(c1.Whens[i].Value, c2.Whens[i].Value)) { return(false); } } return(true); } case SqlNodeType.DiscriminatedType: { SqlDiscriminatedType dt1 = (SqlDiscriminatedType)node1; SqlDiscriminatedType dt2 = (SqlDiscriminatedType)node2; return(AreEqual(dt1.Discriminator, dt2.Discriminator)); } case SqlNodeType.SimpleCase: { SqlSimpleCase c1 = (SqlSimpleCase)node1; SqlSimpleCase c2 = (SqlSimpleCase)node2; if (c1.Whens.Count != c2.Whens.Count) { return(false); } for (int i = 0, n = c1.Whens.Count; i < n; i++) { if (!AreEqual(c1.Whens[i].Match, c2.Whens[i].Match) || !AreEqual(c1.Whens[i].Value, c2.Whens[i].Value)) { return(false); } } return(true); } case SqlNodeType.Like: { SqlLike like1 = (SqlLike)node1; SqlLike like2 = (SqlLike)node2; return(AreEqual(like1.Expression, like2.Expression) && AreEqual(like1.Pattern, like2.Pattern) && AreEqual(like1.Escape, like2.Escape)); } case SqlNodeType.Variable: { SqlVariable v1 = (SqlVariable)node1; SqlVariable v2 = (SqlVariable)node2; return(v1.Name == v2.Name); } case SqlNodeType.FunctionCall: { SqlFunctionCall f1 = (SqlFunctionCall)node1; SqlFunctionCall f2 = (SqlFunctionCall)node2; if (f1.Name != f2.Name) { return(false); } if (f1.Arguments.Count != f2.Arguments.Count) { return(false); } for (int i = 0, n = f1.Arguments.Count; i < n; i++) { if (!AreEqual(f1.Arguments[i], f2.Arguments[i])) { return(false); } } return(true); } case SqlNodeType.Link: { SqlLink l1 = (SqlLink)node1; SqlLink l2 = (SqlLink)node2; if (!MetaPosition.AreSameMember(l1.Member.Member, l2.Member.Member)) { return(false); } if (!AreEqual(l1.Expansion, l2.Expansion)) { return(false); } if (l1.KeyExpressions.Count != l2.KeyExpressions.Count) { return(false); } for (int i = 0, c = l1.KeyExpressions.Count; i < c; ++i) { if (!AreEqual(l1.KeyExpressions[i], l2.KeyExpressions[i])) { return(false); } } return(true); } case SqlNodeType.ExprSet: SqlExprSet es1 = (SqlExprSet)node1; SqlExprSet es2 = (SqlExprSet)node2; if (es1.Expressions.Count != es2.Expressions.Count) { return(false); } for (int i = 0, n = es1.Expressions.Count; i < n; i++) { if (!AreEqual(es1.Expressions[i], es2.Expressions[i])) { return(false); } } return(true); case SqlNodeType.OptionalValue: SqlOptionalValue ov1 = (SqlOptionalValue)node1; SqlOptionalValue ov2 = (SqlOptionalValue)node2; return(AreEqual(ov1.Value, ov2.Value)); case SqlNodeType.Row: case SqlNodeType.UserQuery: case SqlNodeType.StoredProcedureCall: case SqlNodeType.UserRow: case SqlNodeType.UserColumn: case SqlNodeType.Multiset: case SqlNodeType.ScalarSubSelect: case SqlNodeType.Element: case SqlNodeType.Exists: case SqlNodeType.Join: case SqlNodeType.Select: case SqlNodeType.New: case SqlNodeType.ClientQuery: case SqlNodeType.ClientArray: case SqlNodeType.Insert: case SqlNodeType.Update: case SqlNodeType.Delete: case SqlNodeType.MemberAssign: case SqlNodeType.Assign: case SqlNodeType.Block: case SqlNodeType.Union: case SqlNodeType.DoNotVisit: case SqlNodeType.MethodCall: case SqlNodeType.Nop: default: return(false); } }
internal SqlExpression TranslateEquals(SqlBinary expr) { var sqlExpression = expr.Left; var sqlExpression2 = expr.Right; if (sqlExpression2.NodeType == SqlNodeType.Element) { var sqlSubSelect = (SqlSubSelect)sqlExpression2; var sqlAlias = new SqlAlias(sqlSubSelect.Select); var sqlAliasRef = new SqlAliasRef(sqlAlias); var sqlSelect = new SqlSelect(sqlAliasRef, sqlAlias, expr.SourceExpression) { Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(sqlExpression), sqlAliasRef) }; return(sql.SubSelect(SqlNodeType.Exists, sqlSelect)); } if (sqlExpression.NodeType == SqlNodeType.Element) { var sqlSubSelect2 = (SqlSubSelect)sqlExpression; var sqlAlias2 = new SqlAlias(sqlSubSelect2.Select); var sqlAliasRef2 = new SqlAliasRef(sqlAlias2); var sqlSelect2 = new SqlSelect(sqlAliasRef2, sqlAlias2, expr.SourceExpression) { Where = sql.Binary(expr.NodeType, sql.DoNotVisitExpression(sqlExpression2), sqlAliasRef2) }; return(sql.SubSelect(SqlNodeType.Exists, sqlSelect2)); } MetaType sourceMetaType = TypeSource.GetSourceMetaType(sqlExpression, services.Model); MetaType sourceMetaType2 = TypeSource.GetSourceMetaType(sqlExpression2, services.Model); if (sqlExpression.NodeType == SqlNodeType.TypeCase) { sqlExpression = BestIdentityNode((SqlTypeCase)sqlExpression); } if (sqlExpression2.NodeType == SqlNodeType.TypeCase) { sqlExpression2 = BestIdentityNode((SqlTypeCase)sqlExpression2); } if (sourceMetaType.IsEntity && sourceMetaType2.IsEntity && sourceMetaType.Table != sourceMetaType2.Table) { throw Error.CannotCompareItemsAssociatedWithDifferentTable(); } if (!sourceMetaType.IsEntity && !sourceMetaType2.IsEntity && (sqlExpression.NodeType != SqlNodeType.New || sqlExpression.SqlType.CanBeColumn) && (sqlExpression2.NodeType != SqlNodeType.New || sqlExpression2.SqlType.CanBeColumn)) { if (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) { return(TranslateEqualsOp(expr.NodeType, sql.DoNotVisitExpression(expr.Left), sql.DoNotVisitExpression(expr.Right), false)); } return(expr); } if (sourceMetaType != sourceMetaType2 && sourceMetaType.InheritanceRoot != sourceMetaType2.InheritanceRoot) { return(sql.Binary(SqlNodeType.EQ, sql.ValueFromObject(0, expr.SourceExpression), sql.ValueFromObject(1, expr.SourceExpression))); } var sqlLink = sqlExpression as SqlLink; var list = (sqlLink == null || !sqlLink.Member.IsAssociation || !sqlLink.Member.Association.IsForeignKey) ? GetIdentityExpressions(sourceMetaType, sql.DoNotVisitExpression(sqlExpression)) : sqlLink.KeyExpressions; var sqlLink2 = sqlExpression2 as SqlLink; var list2 = (sqlLink2 == null || !sqlLink2.Member.IsAssociation || !sqlLink2.Member.Association.IsForeignKey) ? GetIdentityExpressions(sourceMetaType2, sql.DoNotVisitExpression(sqlExpression2)) : sqlLink2.KeyExpressions; SqlExpression sqlExpression3 = null; var op = (expr.NodeType == SqlNodeType.EQ2V || expr.NodeType == SqlNodeType.NE2V) ? SqlNodeType.EQ2V : SqlNodeType.EQ; var i = 0; for (var count = list.Count; i < count; i++) { var sqlExpression4 = TranslateEqualsOp(op, list[i], list2[i], !sourceMetaType.IsEntity); sqlExpression3 = ((sqlExpression3 != null) ? sql.Binary(SqlNodeType.And, sqlExpression3, sqlExpression4) : sqlExpression4); } if (expr.NodeType == SqlNodeType.NE || expr.NodeType == SqlNodeType.NE2V) { sqlExpression3 = sql.Unary(SqlNodeType.Not, sqlExpression3, sqlExpression3.SourceExpression); } return(sqlExpression3); }
internal override SqlExpression VisitBinaryOperator(SqlBinary bo) { bo.Left = this.VisitExpression(bo.Left); return(bo); }