Skip to content

Commit

Permalink
change SqlGenerator to use dialect specfic bitwise operations identif…
Browse files Browse the repository at this point in the history
…ied as "band", "bor", "bxor" and "bnot" which can be overriden by Subclasses of Dialect
  • Loading branch information
amroel committed Feb 24, 2015
1 parent d9ce463 commit 0a09056
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 16 deletions.
6 changes: 6 additions & 0 deletions src/NHibernate/Dialect/Dialect.cs
Expand Up @@ -113,6 +113,12 @@ protected Dialect()
RegisterFunction("month", new SQLFunctionTemplate(NHibernateUtil.Int32, "extract(month from ?1)"));
RegisterFunction("year", new SQLFunctionTemplate(NHibernateUtil.Int32, "extract(year from ?1)"));

//RegisterFunction("band", new SQLFunctionTemplate(NHibernateUtil.Int64, "?1 & ?2"));
RegisterFunction("band", new NativeBitwiseOpetration("&"));
RegisterFunction("bor", new NativeBitwiseOpetration("|"));
RegisterFunction("bxor", new NativeBitwiseOpetration("^"));
RegisterFunction("bnot", new NativeBitwiseOpetration("~"));

RegisterFunction("str", new SQLFunctionTemplate(NHibernateUtil.String, "cast(?1 as char)"));

// register hibernate types for default use in scalar sqlquery type auto detection
Expand Down
84 changes: 84 additions & 0 deletions src/NHibernate/Dialect/NativeBitwiseOperation.cs
@@ -0,0 +1,84 @@
using System;
using System.Collections;
using NHibernate.Dialect.Function;
using NHibernate.Engine;
using NHibernate.SqlCommand;
using NHibernate.Type;

namespace NHibernate.Dialect
{
[Serializable]
public class NativeBitwiseOperation : ISQLFunction
{
private readonly string _sqlToken;
private Queue _args;
private SqlStringBuilder _sqlBuffer;

public NativeBitwiseOperation(string sqlToken)
{
_sqlToken = sqlToken;
}

#region ISQLFunction Members

public IType ReturnType(IType columnType, IMapping mapping)
{
return NHibernateUtil.Int64;
}

public bool HasArguments
{
get { return true; }
}

public bool HasParenthesesIfNoArguments
{
get { return false; }
}

public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
Prepare(args);
if (_sqlToken != "~")
AddFirstArgument();
AddToken();
AddRestOfArguments();

return _sqlBuffer.ToSqlString();
}

#endregion

private void Prepare(IList args)
{
_sqlBuffer = new SqlStringBuilder();
_args = new Queue(args);
}

private void AddFirstArgument()
{
AddToBuffer(_args.Dequeue());
}

private void AddToken()
{
AddToBuffer(string.Format(" {0} ", _sqlToken));
}

private void AddRestOfArguments()
{
while (_args.Count > 0)
{
AddToBuffer(_args.Dequeue());
}
}

private void AddToBuffer(object arg)
{
if (arg is Parameter || arg is SqlString)
_sqlBuffer.AddObject(arg);
else
_sqlBuffer.Add(arg.ToString());
}
}
}
84 changes: 72 additions & 12 deletions src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.cs
Expand Up @@ -41,7 +41,8 @@ public partial class SqlGenerator : IErrorReporter
private readonly SqlStringBuilder sqlStringBuilder = new SqlStringBuilder();
private ISqlWriter writer;

public SqlGenerator(ISessionFactoryImplementor sfi, ITreeNodeStream input) : this(input)
public SqlGenerator(ISessionFactoryImplementor sfi, ITreeNodeStream input)
: this(input)
{
parseErrorHandler = new ErrorCounter();
sessionFactory = sfi;
Expand Down Expand Up @@ -134,7 +135,7 @@ private void Out(IASTNode n)
}
else if (n is SqlNode)
{
Out(((SqlNode) n).RenderText(sessionFactory));
Out(((SqlNode)n).RenderText(sessionFactory));
}
else
{
Expand All @@ -147,7 +148,7 @@ private void Out(IASTNode n)
}
else if (n is IParameterContainer)
{
var parameterContainer = (IParameterContainer) n;
var parameterContainer = (IParameterContainer)n;
if (parameterContainer.HasEmbeddedParameters)
{
IParameterSpecification[] specifications = parameterContainer.GetEmbeddedParameters();
Expand Down Expand Up @@ -178,8 +179,8 @@ protected virtual void FromFragmentSeparator(IASTNode a)
return;
}

var left = (FromElement) a;
var right = (FromElement) next;
var left = (FromElement)a;
var right = (FromElement)next;

///////////////////////////////////////////////////////////////////////
// HACK ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!
Expand All @@ -192,7 +193,7 @@ protected virtual void FromFragmentSeparator(IASTNode a)
// writes something to the SQL
while (right != null && !HasText(right))
{
right = (FromElement) right.NextSibling;
right = (FromElement)right.NextSibling;
}

if (right == null)
Expand Down Expand Up @@ -235,8 +236,8 @@ protected virtual void NestedFromFragment(IASTNode d, IASTNode parent)
if (parent != null && HasText(parent))
{
// again, both should be FromElements
var left = (FromElement) parent;
var right = (FromElement) d;
var left = (FromElement)parent;
var right = (FromElement)d;
if (right.RealOrigin == left)
{
// right represents a joins originating from left...
Expand Down Expand Up @@ -268,7 +269,7 @@ private SqlStringBuilder GetStringBuilder()

private void BeginFunctionTemplate(IASTNode m, IASTNode i)
{
var methodNode = (MethodNode) m;
var methodNode = (MethodNode)m;
ISQLFunction template = methodNode.SQLFunction;
if (template == null)
{
Expand All @@ -286,7 +287,7 @@ private void BeginFunctionTemplate(IASTNode m, IASTNode i)

private void EndFunctionTemplate(IASTNode m)
{
var methodNode = (MethodNode) m;
var methodNode = (MethodNode)m;
ISQLFunction template = methodNode.SQLFunction;
if (template == null)
{
Expand All @@ -295,7 +296,7 @@ private void EndFunctionTemplate(IASTNode m)
else
{
// this function has a template -> restore output, apply the template and write the result out
var functionArguments = (FunctionArguments) writer; // TODO: Downcast to avoid using an interface? Yuck.
var functionArguments = (FunctionArguments)writer; // TODO: Downcast to avoid using an interface? Yuck.
writer = outputStack[0];
outputStack.RemoveAt(0);
Out(template.Render(functionArguments.Args, sessionFactory));
Expand All @@ -315,7 +316,7 @@ private void StartQuery()

private void EndQuery()
{
SqlString sqlString = GetSqlStringWithLimitsIfNeeded((QueryWriter) writer);
SqlString sqlString = GetSqlStringWithLimitsIfNeeded((QueryWriter)writer);

writer = outputStack[0];
outputStack.RemoveAt(0);
Expand Down Expand Up @@ -381,6 +382,28 @@ private void Take(IASTNode node)
queryWriter.Take = Convert.ToInt32(node.Text);
}

private void BeginBitwiseOp(string op)
{
var function = sessionFactory.SQLFunctionRegistry.FindSQLFunction(op.ToLowerInvariant());
if (function == null)
return;

outputStack.Insert(0, writer);
writer = new BitwiseOperation();
}

private void EndBitwiseOp(string op)
{
ISQLFunction function = sessionFactory.SQLFunctionRegistry.FindSQLFunction(op.ToLowerInvariant());
if (function == null)
return;

var functionArguments = (BitwiseOperation)writer;
writer = outputStack[0];
outputStack.RemoveAt(0);
Out(function.Render(functionArguments.Args, sessionFactory));
}

#region Nested type: DefaultWriter

/// <summary>
Expand Down Expand Up @@ -534,6 +557,43 @@ public void CommaBetweenParameters(string comma)

#endregion

#region Nested type: BitwiseOperation

private class BitwiseOperation : ISqlWriter
{
private readonly List<SqlString> _args = new List<SqlString>();

#region ISqlWriter Members

public void Clause(string clause)
{
Clause(SqlString.Parse(clause));
}

public void Clause(SqlString clause)
{
_args.Add(clause);
}

public void PushParameter(Parameter parameter)
{
_args.Add(new SqlString(parameter));
}

public void CommaBetweenParameters(string comma)
{
}

#endregion

public IList Args
{
get { return _args; }
}
}

#endregion

#region Nested type: ISqlWriter

/// <summary>
Expand Down
8 changes: 4 additions & 4 deletions src/NHibernate/Hql/Ast/ANTLR/SqlGenerator.g
Expand Up @@ -305,10 +305,10 @@ additiveExpr
;
bitwiseExpr
: ^(BAND expr { Out("&"); } nestedExpr)
| ^(BOR expr { Out("|"); } nestedExpr)
| ^(BXOR expr { Out("^"); } nestedExpr)
| ^(BNOT { Out("~"); } nestedExpr)
: ^(BAND { BeginBitwiseOp("band"); } expr nestedExpr { EndBitwiseOp("band"); })
| ^(BOR { BeginBitwiseOp("bor"); } expr nestedExpr { EndBitwiseOp("bor"); })
| ^(BXOR { BeginBitwiseOp("bxor"); } expr nestedExpr { EndBitwiseOp("bxor"); })
| ^(BNOT { BeginBitwiseOp("bnot"); } nestedExpr { EndBitwiseOp("bnot"); })
;
multiplicativeExpr
Expand Down
1 change: 1 addition & 0 deletions src/NHibernate/NHibernate.csproj
Expand Up @@ -156,6 +156,7 @@
<Compile Include="Dialect\MySQL55InnoDBDialect.cs" />
<Compile Include="Dialect\MySQL5InnoDBDialect.cs" />
<Compile Include="Dialect\MySQLDialect.cs" />
<Compile Include="Dialect\NativeBitwiseOperation.cs" />
<Compile Include="Dialect\PostgreSQLDialect.cs" />
<Compile Include="Dialect\Schema\PostgreSQLMetadata.cs" />
<Compile Include="Dialect\Schema\SchemaHelper.cs" />
Expand Down

0 comments on commit 0a09056

Please sign in to comment.