1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
using System;
using System.Collections.Generic;
using System.Text;
namespace System.Data.Linq.SqlClient
{
/// <summary>
/// Find referenced Aliases within a node.
/// </summary>
internal static class SqlAliasesReferenced
{
/// <summary>
/// Private visitor which walks the tree and looks for referenced aliases.
/// </summary>
private class Visitor : SqlVisitor {
internal IEnumerable<SqlAlias> aliases;
internal bool referencesAnyMatchingAliases = false;
internal override SqlNode Visit(SqlNode node) {
// Short-circuit when the answer is alreading known
if (this.referencesAnyMatchingAliases) {
return node;
}
return base.Visit(node);
}
internal SqlAlias VisitAliasConsumed(SqlAlias a) {
if (a == null)
return a;
bool match = false;
foreach (SqlAlias alias in aliases)
if (alias == a) {
match = true;
break;
}
if (match) {
this.referencesAnyMatchingAliases = true;
}
return a;
}
internal override SqlExpression VisitColumn(SqlColumn col) {
VisitAliasConsumed(col.Alias);
VisitExpression(col.Expression);
return col;
}
internal override SqlExpression VisitColumnRef(SqlColumnRef cref) {
VisitAliasConsumed(cref.Column.Alias);
VisitExpression(cref.Column.Expression);
return cref;
}
}
/// <summary>
/// Returns true iff the given node references any aliases the list of 'aliases'.
/// </summary>
internal static bool ReferencesAny(SqlNode node, IEnumerable<SqlAlias> aliases) {
Visitor visitor = new Visitor();
visitor.aliases = aliases;
visitor.Visit(node);
return visitor.referencesAnyMatchingAliases;
}
}
}
|