2016-08-03 10:59:49 +00:00
using System ;
using System.Collections.Generic ;
using System.Data.Linq ;
using System.Diagnostics ;
using System.Diagnostics.CodeAnalysis ;
namespace System.Data.Linq.SqlClient {
internal abstract class SqlVisitor {
int nDepth ;
// Visit a SqlNode
2017-08-21 15:34:15 +00:00
[SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="Microsoft: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")]
2016-08-03 10:59:49 +00:00
[SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
internal virtual SqlNode Visit ( SqlNode node ) {
SqlNode result = null ;
if ( node = = null ) {
return null ;
}
try {
nDepth + + ;
CheckRecursionDepth ( 500 , nDepth ) ;
switch ( node . NodeType ) {
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 . OuterJoinedValue :
case SqlNodeType . ClrLength :
result = this . VisitUnaryOperator ( ( SqlUnary ) node ) ;
break ;
case SqlNodeType . Lift :
result = this . VisitLift ( ( SqlLift ) node ) ;
break ;
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 :
result = this . VisitBinaryOperator ( ( SqlBinary ) node ) ;
break ;
case SqlNodeType . Between :
result = this . VisitBetween ( ( SqlBetween ) node ) ;
break ;
case SqlNodeType . In :
result = this . VisitIn ( ( SqlIn ) node ) ;
break ;
case SqlNodeType . Like :
result = this . VisitLike ( ( SqlLike ) node ) ;
break ;
case SqlNodeType . Treat :
result = this . VisitTreat ( ( SqlUnary ) node ) ;
break ;
case SqlNodeType . Alias :
result = this . VisitAlias ( ( SqlAlias ) node ) ;
break ;
case SqlNodeType . AliasRef :
result = this . VisitAliasRef ( ( SqlAliasRef ) node ) ;
break ;
case SqlNodeType . Member :
result = this . VisitMember ( ( SqlMember ) node ) ;
break ;
case SqlNodeType . Row :
result = this . VisitRow ( ( SqlRow ) node ) ;
break ;
case SqlNodeType . Column :
result = this . VisitColumn ( ( SqlColumn ) node ) ;
break ;
case SqlNodeType . ColumnRef :
result = this . VisitColumnRef ( ( SqlColumnRef ) node ) ;
break ;
case SqlNodeType . Table :
result = this . VisitTable ( ( SqlTable ) node ) ;
break ;
case SqlNodeType . UserQuery :
result = this . VisitUserQuery ( ( SqlUserQuery ) node ) ;
break ;
case SqlNodeType . StoredProcedureCall :
result = this . VisitStoredProcedureCall ( ( SqlStoredProcedureCall ) node ) ;
break ;
case SqlNodeType . UserRow :
result = this . VisitUserRow ( ( SqlUserRow ) node ) ;
break ;
case SqlNodeType . UserColumn :
result = this . VisitUserColumn ( ( SqlUserColumn ) node ) ;
break ;
case SqlNodeType . Multiset :
case SqlNodeType . ScalarSubSelect :
case SqlNodeType . Element :
case SqlNodeType . Exists :
result = this . VisitSubSelect ( ( SqlSubSelect ) node ) ;
break ;
case SqlNodeType . Join :
result = this . VisitJoin ( ( SqlJoin ) node ) ;
break ;
case SqlNodeType . Select :
result = this . VisitSelect ( ( SqlSelect ) node ) ;
break ;
case SqlNodeType . Parameter :
result = this . VisitParameter ( ( SqlParameter ) node ) ;
break ;
case SqlNodeType . New :
result = this . VisitNew ( ( SqlNew ) node ) ;
break ;
case SqlNodeType . Link :
result = this . VisitLink ( ( SqlLink ) node ) ;
break ;
case SqlNodeType . ClientQuery :
result = this . VisitClientQuery ( ( SqlClientQuery ) node ) ;
break ;
case SqlNodeType . JoinedCollection :
result = this . VisitJoinedCollection ( ( SqlJoinedCollection ) node ) ;
break ;
case SqlNodeType . Value :
result = this . VisitValue ( ( SqlValue ) node ) ;
break ;
case SqlNodeType . ClientArray :
result = this . VisitClientArray ( ( SqlClientArray ) node ) ;
break ;
case SqlNodeType . Insert :
result = this . VisitInsert ( ( SqlInsert ) node ) ;
break ;
case SqlNodeType . Update :
result = this . VisitUpdate ( ( SqlUpdate ) node ) ;
break ;
case SqlNodeType . Delete :
result = this . VisitDelete ( ( SqlDelete ) node ) ;
break ;
case SqlNodeType . MemberAssign :
result = this . VisitMemberAssign ( ( SqlMemberAssign ) node ) ;
break ;
case SqlNodeType . Assign :
result = this . VisitAssign ( ( SqlAssign ) node ) ;
break ;
case SqlNodeType . Block :
result = this . VisitBlock ( ( SqlBlock ) node ) ;
break ;
case SqlNodeType . SearchedCase :
result = this . VisitSearchedCase ( ( SqlSearchedCase ) node ) ;
break ;
case SqlNodeType . ClientCase :
result = this . VisitClientCase ( ( SqlClientCase ) node ) ;
break ;
case SqlNodeType . SimpleCase :
result = this . VisitSimpleCase ( ( SqlSimpleCase ) node ) ;
break ;
case SqlNodeType . TypeCase :
result = this . VisitTypeCase ( ( SqlTypeCase ) node ) ;
break ;
case SqlNodeType . Union :
result = this . VisitUnion ( ( SqlUnion ) node ) ;
break ;
case SqlNodeType . ExprSet :
result = this . VisitExprSet ( ( SqlExprSet ) node ) ;
break ;
case SqlNodeType . Variable :
result = this . VisitVariable ( ( SqlVariable ) node ) ;
break ;
case SqlNodeType . DoNotVisit :
result = this . VisitDoNotVisit ( ( SqlDoNotVisitExpression ) node ) ;
break ;
case SqlNodeType . OptionalValue :
result = this . VisitOptionalValue ( ( SqlOptionalValue ) node ) ;
break ;
case SqlNodeType . FunctionCall :
result = this . VisitFunctionCall ( ( SqlFunctionCall ) node ) ;
break ;
case SqlNodeType . TableValuedFunctionCall :
result = this . VisitTableValuedFunctionCall ( ( SqlTableValuedFunctionCall ) node ) ;
break ;
case SqlNodeType . MethodCall :
result = this . VisitMethodCall ( ( SqlMethodCall ) node ) ;
break ;
case SqlNodeType . Nop :
result = this . VisitNop ( ( SqlNop ) node ) ;
break ;
case SqlNodeType . SharedExpression :
result = this . VisitSharedExpression ( ( SqlSharedExpression ) node ) ;
break ;
case SqlNodeType . SharedExpressionRef :
result = this . VisitSharedExpressionRef ( ( SqlSharedExpressionRef ) node ) ;
break ;
case SqlNodeType . SimpleExpression :
result = this . VisitSimpleExpression ( ( SqlSimpleExpression ) node ) ;
break ;
case SqlNodeType . Grouping :
result = this . VisitGrouping ( ( SqlGrouping ) node ) ;
break ;
case SqlNodeType . DiscriminatedType :
result = this . VisitDiscriminatedType ( ( SqlDiscriminatedType ) node ) ;
break ;
case SqlNodeType . DiscriminatorOf :
result = this . VisitDiscriminatorOf ( ( SqlDiscriminatorOf ) node ) ;
break ;
case SqlNodeType . ClientParameter :
result = this . VisitClientParameter ( ( SqlClientParameter ) node ) ;
break ;
case SqlNodeType . RowNumber :
result = this . VisitRowNumber ( ( SqlRowNumber ) node ) ;
break ;
case SqlNodeType . IncludeScope :
result = this . VisitIncludeScope ( ( SqlIncludeScope ) node ) ;
break ;
default :
throw Error . UnexpectedNode ( node ) ;
}
} finally {
this . nDepth - - ;
}
return result ;
}
/// <summary>
/// This method checks the recursion level to help diagnose/prevent
/// infinite recursion in debug builds. Calls are ommitted in non debug builds.
/// </summary>
[SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Justification="Debug-only code.")]
[Conditional("DEBUG")]
internal static void CheckRecursionDepth ( int maxLevel , int level ) {
if ( level > maxLevel ) {
System . Diagnostics . Debug . Assert ( false ) ;
//**********************************************************************
// EXCLUDING FROM LOCALIZATION.
// Reason: This code only executes in DEBUG.
throw new Exception ( "Infinite Descent?" ) ;
//**********************************************************************
}
}
[SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")]
internal object Eval ( SqlExpression expr ) {
if ( expr . NodeType = = SqlNodeType . Value ) {
return ( ( SqlValue ) expr ) . Value ;
}
throw Error . UnexpectedNode ( expr . NodeType ) ;
}
internal virtual SqlExpression VisitDoNotVisit ( SqlDoNotVisitExpression expr ) {
return expr . Expression ;
}
internal virtual SqlRowNumber VisitRowNumber ( SqlRowNumber rowNumber ) {
for ( int i = 0 , n = rowNumber . OrderBy . Count ; i < n ; i + + ) {
rowNumber . OrderBy [ i ] . Expression = this . VisitExpression ( rowNumber . OrderBy [ i ] . Expression ) ;
}
return rowNumber ;
}
internal virtual SqlExpression VisitExpression ( SqlExpression exp ) {
return ( SqlExpression ) this . Visit ( exp ) ;
}
internal virtual SqlSelect VisitSequence ( SqlSelect sel ) {
return ( SqlSelect ) this . Visit ( sel ) ;
}
internal virtual SqlExpression VisitNop ( SqlNop nop ) {
return nop ;
}
internal virtual SqlExpression VisitLift ( SqlLift lift ) {
lift . Expression = this . VisitExpression ( lift . Expression ) ;
return lift ;
}
internal virtual SqlExpression VisitUnaryOperator ( SqlUnary uo ) {
uo . Operand = this . VisitExpression ( uo . Operand ) ;
return uo ;
}
internal virtual SqlExpression VisitBinaryOperator ( SqlBinary bo ) {
bo . Left = this . VisitExpression ( bo . Left ) ;
bo . Right = this . VisitExpression ( bo . Right ) ;
return bo ;
}
internal virtual SqlAlias VisitAlias ( SqlAlias a ) {
a . Node = this . Visit ( a . Node ) ;
return a ;
}
internal virtual SqlExpression VisitAliasRef ( SqlAliasRef aref ) {
return aref ;
}
internal virtual SqlNode VisitMember ( SqlMember m ) {
m . Expression = this . VisitExpression ( m . Expression ) ;
return m ;
}
internal virtual SqlExpression VisitCast ( SqlUnary c ) {
c . Operand = this . VisitExpression ( c . Operand ) ;
return c ;
}
internal virtual SqlExpression VisitTreat ( SqlUnary t ) {
t . Operand = this . VisitExpression ( t . Operand ) ;
return t ;
}
internal virtual SqlTable VisitTable ( SqlTable tab ) {
return tab ;
}
internal virtual SqlUserQuery VisitUserQuery ( SqlUserQuery suq ) {
for ( int i = 0 , n = suq . Arguments . Count ; i < n ; i + + ) {
suq . Arguments [ i ] = this . VisitExpression ( suq . Arguments [ i ] ) ;
}
suq . Projection = this . VisitExpression ( suq . Projection ) ;
for ( int i = 0 , n = suq . Columns . Count ; i < n ; i + + ) {
suq . Columns [ i ] = ( SqlUserColumn ) this . Visit ( suq . Columns [ i ] ) ;
}
return suq ;
}
internal virtual SqlStoredProcedureCall VisitStoredProcedureCall ( SqlStoredProcedureCall spc ) {
for ( int i = 0 , n = spc . Arguments . Count ; i < n ; i + + ) {
spc . Arguments [ i ] = this . VisitExpression ( spc . Arguments [ i ] ) ;
}
spc . Projection = this . VisitExpression ( spc . Projection ) ;
for ( int i = 0 , n = spc . Columns . Count ; i < n ; i + + ) {
spc . Columns [ i ] = ( SqlUserColumn ) this . Visit ( spc . Columns [ i ] ) ;
}
return spc ;
}
internal virtual SqlExpression VisitUserColumn ( SqlUserColumn suc ) {
return suc ;
}
internal virtual SqlExpression VisitUserRow ( SqlUserRow row ) {
return row ;
}
internal virtual SqlRow VisitRow ( SqlRow row ) {
for ( int i = 0 , n = row . Columns . Count ; i < n ; i + + ) {
row . Columns [ i ] . Expression = this . VisitExpression ( row . Columns [ i ] . Expression ) ;
}
return row ;
}
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 ;
}
internal virtual SqlNode VisitLink ( SqlLink link ) {
// Don't visit the link's Expansion
for ( int i = 0 , n = link . KeyExpressions . Count ; i < n ; i + + ) {
link . KeyExpressions [ i ] = this . VisitExpression ( link . KeyExpressions [ i ] ) ;
}
return link ;
}
internal virtual SqlExpression VisitClientQuery ( SqlClientQuery cq ) {
for ( int i = 0 , n = cq . Arguments . Count ; i < n ; i + + ) {
cq . Arguments [ i ] = this . VisitExpression ( cq . Arguments [ i ] ) ;
}
return cq ;
}
internal virtual SqlExpression VisitJoinedCollection ( SqlJoinedCollection jc ) {
jc . Expression = this . VisitExpression ( jc . Expression ) ;
jc . Count = this . VisitExpression ( jc . Count ) ;
return jc ;
}
internal virtual SqlExpression VisitClientArray ( SqlClientArray scar ) {
for ( int i = 0 , n = scar . Expressions . Count ; i < n ; i + + ) {
scar . Expressions [ i ] = this . VisitExpression ( scar . Expressions [ i ] ) ;
}
return scar ;
}
internal virtual SqlExpression VisitClientParameter ( SqlClientParameter cp ) {
return cp ;
}
internal virtual SqlExpression VisitColumn ( SqlColumn col ) {
col . Expression = this . VisitExpression ( col . Expression ) ;
return col ;
}
internal virtual SqlExpression VisitColumnRef ( SqlColumnRef cref ) {
return cref ;
}
internal virtual SqlExpression VisitParameter ( SqlParameter p ) {
return p ;
}
internal virtual SqlExpression VisitValue ( SqlValue value ) {
return value ;
}
internal virtual SqlExpression VisitSubSelect ( SqlSubSelect ss ) {
switch ( ss . NodeType ) {
case SqlNodeType . ScalarSubSelect : return this . VisitScalarSubSelect ( ss ) ;
case SqlNodeType . Multiset : return this . VisitMultiset ( ss ) ;
case SqlNodeType . Element : return this . VisitElement ( ss ) ;
case SqlNodeType . Exists : return this . VisitExists ( ss ) ;
}
throw Error . UnexpectedNode ( ss . NodeType ) ;
}
internal virtual SqlExpression VisitScalarSubSelect ( SqlSubSelect ss ) {
ss . Select = this . VisitSequence ( ss . Select ) ;
return ss ;
}
internal virtual SqlExpression VisitMultiset ( SqlSubSelect sms ) {
sms . Select = this . VisitSequence ( sms . Select ) ;
return sms ;
}
internal virtual SqlExpression VisitElement ( SqlSubSelect elem ) {
elem . Select = this . VisitSequence ( elem . Select ) ;
return elem ;
}
internal virtual SqlExpression VisitExists ( SqlSubSelect sqlExpr ) {
sqlExpr . Select = this . VisitSequence ( sqlExpr . Select ) ;
return sqlExpr ;
}
internal virtual SqlSource VisitJoin ( SqlJoin join ) {
join . Left = this . VisitSource ( join . Left ) ;
join . Right = this . VisitSource ( join . Right ) ;
join . Condition = this . VisitExpression ( join . Condition ) ;
return join ;
}
internal virtual SqlSource VisitSource ( SqlSource source ) {
return ( SqlSource ) this . Visit ( source ) ;
}
internal virtual SqlSelect VisitSelectCore ( SqlSelect select ) {
select . From = this . VisitSource ( select . From ) ;
select . Where = this . VisitExpression ( select . Where ) ;
for ( int i = 0 , n = select . GroupBy . Count ; i < n ; i + + ) {
select . GroupBy [ i ] = this . VisitExpression ( select . GroupBy [ i ] ) ;
}
select . Having = this . VisitExpression ( select . Having ) ;
for ( int i = 0 , n = select . OrderBy . Count ; i < n ; i + + ) {
select . OrderBy [ i ] . Expression = this . VisitExpression ( select . OrderBy [ i ] . Expression ) ;
}
select . Top = this . VisitExpression ( select . Top ) ;
select . Row = ( SqlRow ) this . Visit ( select . Row ) ;
return select ;
}
internal virtual SqlSelect VisitSelect ( SqlSelect select ) {
select = this . VisitSelectCore ( select ) ;
select . Selection = this . VisitExpression ( select . Selection ) ;
return select ;
}
internal virtual SqlStatement VisitInsert ( SqlInsert insert ) {
insert . Table = ( SqlTable ) this . Visit ( insert . Table ) ;
insert . Expression = this . VisitExpression ( insert . Expression ) ;
insert . Row = ( SqlRow ) this . Visit ( insert . Row ) ;
return insert ;
}
internal virtual SqlStatement VisitUpdate ( SqlUpdate update ) {
update . Select = this . VisitSequence ( update . Select ) ;
for ( int i = 0 , n = update . Assignments . Count ; i < n ; i + + ) {
update . Assignments [ i ] = ( SqlAssign ) this . Visit ( update . Assignments [ i ] ) ;
}
return update ;
}
internal virtual SqlStatement VisitDelete ( SqlDelete delete ) {
delete . Select = this . VisitSequence ( delete . Select ) ;
return delete ;
}
internal virtual SqlMemberAssign VisitMemberAssign ( SqlMemberAssign ma ) {
ma . Expression = this . VisitExpression ( ma . Expression ) ;
return ma ;
}
internal virtual SqlStatement VisitAssign ( SqlAssign sa ) {
sa . LValue = this . VisitExpression ( sa . LValue ) ;
sa . RValue = this . VisitExpression ( sa . RValue ) ;
return sa ;
}
internal virtual SqlBlock VisitBlock ( SqlBlock b ) {
for ( int i = 0 , n = b . Statements . Count ; i < n ; i + + ) {
b . Statements [ i ] = ( SqlStatement ) this . Visit ( b . Statements [ i ] ) ;
}
return b ;
}
internal virtual SqlExpression VisitSearchedCase ( SqlSearchedCase c ) {
for ( int i = 0 , n = c . Whens . Count ; i < n ; i + + ) {
SqlWhen when = c . Whens [ i ] ;
when . Match = this . VisitExpression ( when . Match ) ;
when . Value = this . VisitExpression ( when . Value ) ;
}
c . Else = this . VisitExpression ( c . Else ) ;
return c ;
}
internal virtual SqlExpression VisitClientCase ( SqlClientCase c ) {
c . Expression = this . VisitExpression ( c . Expression ) ;
for ( int i = 0 , n = c . Whens . Count ; i < n ; i + + ) {
SqlClientWhen when = c . Whens [ i ] ;
when . Match = this . VisitExpression ( when . Match ) ;
when . Value = this . VisitExpression ( when . Value ) ;
}
return c ;
}
internal virtual SqlExpression VisitSimpleCase ( SqlSimpleCase c ) {
c . Expression = this . VisitExpression ( c . Expression ) ;
for ( int i = 0 , n = c . Whens . Count ; i < n ; i + + ) {
SqlWhen when = c . Whens [ i ] ;
when . Match = this . VisitExpression ( when . Match ) ;
when . Value = this . VisitExpression ( when . Value ) ;
}
return c ;
}
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 ;
}
internal virtual SqlNode VisitUnion ( SqlUnion su ) {
su . Left = this . Visit ( su . Left ) ;
su . Right = this . Visit ( su . Right ) ;
return su ;
}
internal virtual SqlExpression VisitExprSet ( SqlExprSet xs ) {
for ( int i = 0 , n = xs . Expressions . Count ; i < n ; i + + ) {
xs . Expressions [ i ] = this . VisitExpression ( xs . Expressions [ i ] ) ;
}
return xs ;
}
internal virtual SqlExpression VisitVariable ( SqlVariable v ) {
return v ;
}
internal virtual SqlExpression VisitOptionalValue ( SqlOptionalValue sov ) {
sov . HasValue = this . VisitExpression ( sov . HasValue ) ;
sov . Value = this . VisitExpression ( sov . Value ) ;
return sov ;
}
internal virtual SqlExpression VisitBetween ( SqlBetween between ) {
between . Expression = this . VisitExpression ( between . Expression ) ;
between . Start = this . VisitExpression ( between . Start ) ;
between . End = this . VisitExpression ( between . End ) ;
return between ;
}
internal virtual SqlExpression VisitIn ( SqlIn sin ) {
sin . Expression = this . VisitExpression ( sin . Expression ) ;
for ( int i = 0 , n = sin . Values . Count ; i < n ; i + + ) {
sin . Values [ i ] = this . VisitExpression ( sin . Values [ i ] ) ;
}
return sin ;
}
internal virtual SqlExpression VisitLike ( SqlLike like ) {
like . Expression = this . VisitExpression ( like . Expression ) ;
like . Pattern = this . VisitExpression ( like . Pattern ) ;
like . Escape = this . VisitExpression ( like . Escape ) ;
return like ;
}
internal virtual SqlExpression VisitFunctionCall ( SqlFunctionCall fc ) {
for ( int i = 0 , n = fc . Arguments . Count ; i < n ; i + + ) {
fc . Arguments [ i ] = this . VisitExpression ( fc . Arguments [ i ] ) ;
}
return fc ;
}
internal virtual SqlExpression VisitTableValuedFunctionCall ( SqlTableValuedFunctionCall fc ) {
for ( int i = 0 , n = fc . Arguments . Count ; i < n ; i + + ) {
fc . Arguments [ i ] = this . VisitExpression ( fc . Arguments [ i ] ) ;
}
return fc ;
}
internal virtual SqlExpression VisitMethodCall ( SqlMethodCall mc ) {
mc . Object = this . VisitExpression ( mc . Object ) ;
for ( int i = 0 , n = mc . Arguments . Count ; i < n ; i + + ) {
mc . Arguments [ i ] = this . VisitExpression ( mc . Arguments [ i ] ) ;
}
return mc ;
}
internal virtual SqlExpression VisitSharedExpression ( SqlSharedExpression shared ) {
shared . Expression = this . VisitExpression ( shared . Expression ) ;
return shared ;
}
internal virtual SqlExpression VisitSharedExpressionRef ( SqlSharedExpressionRef sref ) {
return sref ;
}
internal virtual SqlExpression VisitSimpleExpression ( SqlSimpleExpression simple ) {
simple . Expression = this . VisitExpression ( simple . Expression ) ;
return simple ;
}
internal virtual SqlExpression VisitGrouping ( SqlGrouping g ) {
g . Key = this . VisitExpression ( g . Key ) ;
g . Group = this . VisitExpression ( g . Group ) ;
return g ;
}
internal virtual SqlExpression VisitDiscriminatedType ( SqlDiscriminatedType dt ) {
dt . Discriminator = this . VisitExpression ( dt . Discriminator ) ;
return dt ;
}
internal virtual SqlExpression VisitDiscriminatorOf ( SqlDiscriminatorOf dof ) {
dof . Object = this . VisitExpression ( dof . Object ) ;
return dof ;
}
internal virtual SqlNode VisitIncludeScope ( SqlIncludeScope node ) {
node . Child = this . Visit ( node . Child ) ;
return node ;
}
#if DEBUG
int refersDepth ;
#endif
internal bool RefersToColumn ( SqlExpression exp , SqlColumn col ) {
#if DEBUG
try {
refersDepth + + ;
System . Diagnostics . Debug . Assert ( refersDepth < 20 ) ;
#endif
if ( exp ! = null ) {
switch ( exp . NodeType ) {
case SqlNodeType . Column :
return exp = = col | | this . RefersToColumn ( ( ( SqlColumn ) exp ) . Expression , col ) ;
case SqlNodeType . ColumnRef :
SqlColumnRef cref = ( SqlColumnRef ) exp ;
return cref . Column = = col | | this . RefersToColumn ( cref . Column . Expression , col ) ;
case SqlNodeType . ExprSet :
SqlExprSet set = ( SqlExprSet ) exp ;
for ( int i = 0 , n = set . Expressions . Count ; i < n ; i + + ) {
if ( this . RefersToColumn ( set . Expressions [ i ] , col ) ) {
return true ;
}
}
break ;
case SqlNodeType . OuterJoinedValue :
return this . RefersToColumn ( ( ( SqlUnary ) exp ) . Operand , col ) ;
}
}
return false ;
#if DEBUG
}
finally {
refersDepth - - ;
}
#endif
}
}
}