Skip to content

Commit

Permalink
AliasBinder works
Browse files Browse the repository at this point in the history
  • Loading branch information
vchekan committed Jul 29, 2010
1 parent c92a53a commit caf39bf
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 15 deletions.
9 changes: 8 additions & 1 deletion CodeQL.mdp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
<File subtype="Code" buildaction="Compile" name="CqlAst/Node.cs" />
<File subtype="Code" buildaction="Compile" name="CqlAst/StatementNode.cs" />
<File subtype="Code" buildaction="Compile" name="CqlAst/SelectColumnNode.cs" />
<File subtype="Code" buildaction="Compile" name="TranslatorException.cs" />
<File subtype="Code" buildaction="Compile" name="CqlAst/JoinType.cs" />
<File subtype="Code" buildaction="Compile" name="Translate/AliasBinder.cs" />
<File subtype="Code" buildaction="Compile" name="CqlAst/JoinNode.cs" />
Expand All @@ -71,6 +70,14 @@
<File subtype="Directory" buildaction="Compile" name="." />
<File subtype="Code" buildaction="Nothing" name="parsers/cs/cs2.y" />
<File subtype="Directory" buildaction="Compile" name="." />
<File subtype="Code" buildaction="Compile" name="CqlAst/DataSource.cs" />
<File subtype="Code" buildaction="Compile" name="Translate/ITranslationPlugin.cs" />
<File subtype="Directory" buildaction="Compile" name="Linq" />
<File subtype="Code" buildaction="Compile" name="Linq/Enumerable.cs" />
<File subtype="Directory" buildaction="Compile" name="Exceptions" />
<File subtype="Code" buildaction="Compile" name="Exceptions/TranslatorException.cs" />
<File subtype="Directory" buildaction="Compile" name="." />
<File subtype="Code" buildaction="Compile" name="Exceptions/UnresolvedAliasException.cs" />
</Contents>
<MonoDevelop.Autotools.MakefileInfo RelativeMakefileName="Makefile" BuildTargetName="build">
<BuildFilesVar />
Expand Down
2 changes: 1 addition & 1 deletion CodeQL.mds
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<Entry build="True" name="CodeQL.Testing" configuration="Release" />
</Configuration>
</Configurations>
<StartMode startupentry="CodeQL.Testing" single="True">
<StartMode startupentry="CodeQL.Console" single="True">
<Execute type="None" entry="CodeQL" />
<Execute type="None" entry="SQLDetector" />
<Execute type="None" entry="CodeQL.UI" />
Expand Down
2 changes: 2 additions & 0 deletions CqlAst/ColumnExpressionNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class ColumnExpressionNode : ExpressionNode
{
public string Name;
public string TableAlias;
/// <summary>Is set in run time by AliasBinder</summary>
public DataSourceNode AliasReference;

public override IEnumerable<INode> Children {
get {yield break;}
Expand Down
32 changes: 32 additions & 0 deletions CqlAst/DataSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// DataSource.cs
//
// Author:
// Vadim Chekan <[email protected]>
//
// Copyright (c) 2010 Vadim Chekan
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
using System;
namespace CodeQL {
/// <summary>
/// Table in FROM or JOIN clause or sub-select.
/// </summary>
public abstract class DataSourceNode : Node {
public string Alias;
}
}

3 changes: 1 addition & 2 deletions CqlAst/TableNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@
namespace CodeQL
{

public class TableNode : Node
public class TableNode : DataSourceNode
{
public string Name;
public string Alias;

public override IEnumerable<INode> Children {
get {yield break;}
Expand Down
File renamed without changes.
32 changes: 32 additions & 0 deletions Exceptions/UnresolvedAliasException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// UnresolvedAliasException.cs
//
// Author:
// Vadim Chekan <[email protected]>
//
// Copyright (c) 2010 Vadim Chekan
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
using System;
namespace CodeQL {
public class UnresolvedAliasException : TranslatorException {
public UnresolvedAliasException(ColumnExpressionNode column)
: base(string.Format("Alias not found: '{0}.{1}'", column.TableAlias, column.Name))
{
}
}
}

34 changes: 34 additions & 0 deletions Linq/Enumerable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//
// Enumerable.cs
//
// Author:
// Vadim Chekan <[email protected]>
//
// Copyright (c) 2010 Vadim Chekan
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
using System;
using System.Collections.Generic;

namespace CodeQL {
public static class EnumerableEx {
public static void ForEach<T>(this IEnumerable<T> list, Action<T> action) {
foreach(T x in list)
action(x);
}
}
}

41 changes: 36 additions & 5 deletions Translate/AliasBinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,47 @@
using System.Linq;

namespace CodeQL {
public class AliasBinder {
public class AliasBinder : ITranslationPlugin {

public void Init() {/*empty*/}

public void Run() {
/*
* TODO: account for scope when subquery is implemented
* Note: aliases have scope. Alias in subquery can override alias from the outer one.
* Also alias can not be visible from sibling subqueries.
*/
var aliasTableMap = new GraphIterator<INode>(TranslationContext.Batch, node => node.Children).
BreadthFirst().
OfType<TableNode>().
ToDictionary(t => t.Alias, StringComparer.OrdinalIgnoreCase);

//
// Build alias map
//
var dataSources = new GraphIterator<INode>(TranslationContext.Instance.Batch, node => node.Children).
DepthFirst().
OfType<DataSourceNode>();

var aliasMap = new Dictionary<string,DataSourceNode>(StringComparer.OrdinalIgnoreCase);
foreach(var ds in dataSources)
if(aliasMap.ContainsKey(ds.Alias))
throw new ApplicationException("Alias '"+ds.Alias+"' is declared twice");
else
aliasMap.Add(ds.Alias, ds);

//
new GraphIterator<INode>(TranslationContext.Instance.Batch, n => n.Children).
DepthFirst().
OfType<ColumnExpressionNode>().
ForEach(c => {
DataSourceNode dataSource;
if(!aliasMap.TryGetValue(c.TableAlias, out dataSource))
throw new UnresolvedAliasException(c);
c.AliasReference = dataSource;
});

// fire binding events
foreach(var p in aliasMap)
if(TranslationContext.Instance.OnTableAliasBound != null)
TranslationContext.Instance.OnTableAliasBound(p.Key, p.Value);

}
}
}
2 changes: 1 addition & 1 deletion Translate/ClassHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ static ClassHandler() {
}

public void Run() {
var classTables = new GraphIterator<INode>(TranslationContext.Batch, n => n.Children).
var classTables = new GraphIterator<INode>(TranslationContext.Instance.Batch, n => n.Children).
BreadthFirst().
OfType<TableNode>().
Where(t => t.Name.Equals("class", StringComparison.InvariantCultureIgnoreCase));
Expand Down
30 changes: 30 additions & 0 deletions Translate/ITranslationPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// ITranslationPlugin.cs
//
// Author:
// Vadim Chekan <[email protected]>
//
// Copyright (c) 2010 Vadim Chekan
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
using System;
namespace CodeQL {
public interface ITranslationPlugin {
void Init();
void Run();
}
}

15 changes: 10 additions & 5 deletions Translate/TranslationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,31 @@
using System;

namespace CodeQL {


public class TranslationContext : IDisposable {

[ThreadStatic]
static TranslationContext _instance;

BatchNode _batch;

//
//
//
public TranslationContext(BatchNode batch) {
if(_instance != null)
throw new ApplicationException("Context already initialized");
_instance = this;
_batch = batch;
}

private static TranslationContext Instance {
public static TranslationContext Instance {
get {
if(_instance == null)
throw new ApplicationException("Context not initilized");
return _instance;
}
}

public static BatchNode Batch {
public BatchNode Batch {
get { return Instance._batch; }
internal set { Instance._batch = value; }
}
Expand All @@ -58,5 +59,9 @@ void IDisposable.Dispose() {
_instance = null;
}

//
// Events
//
public Action<string,DataSourceNode> OnTableAliasBound;
}
}

0 comments on commit caf39bf

Please sign in to comment.