|
From: <fab...@us...> - 2008-08-13 14:59:15
|
Revision: 3701
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3701&view=rev
Author: fabiomaulo
Date: 2008-08-13 14:59:18 +0000 (Wed, 13 Aug 2008)
Log Message:
-----------
Support of parametrs in HQLFunctions (by Ricardo Stuven)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs
trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs
trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs
trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs
trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs
trunk/nhibernate/src/NHibernate/SqlCommand/ISqlStringVisitor.cs
trunk/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SqlStringBuilder.cs
trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/HQLFunctions.cs
trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SQLFunctionTemplateTest.cs
trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SimpleFunctionsTest.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Criterion/SqlFunctionProjection.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -78,7 +78,7 @@
{
tokens.Add(replacemenToken);
}
- string functionStatement = sqlFunction.Render(tokens, criteriaQuery.Factory);
+ string functionStatement = sqlFunction.Render(tokens, criteriaQuery.Factory).ToString();
string[] splitted = functionStatement.Split(new string[] {replacemenToken}, StringSplitOptions.RemoveEmptyEntries);
SqlStringBuilder sb = new SqlStringBuilder();
@@ -138,4 +138,4 @@
return types.ToArray();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/FirebirdDialect.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -221,10 +221,15 @@
{
}
- public override string Render(IList args, ISessionFactoryImplementor factory)
+ public override SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- base.Render(args, factory);
- return string.Format("cast('{0}' as {1})", Name, FunctionReturnType.SqlTypes(factory)[0]);
+ return new SqlStringBuilder()
+ .Add("cast('")
+ .Add(name)
+ .Add("' as ")
+ .Add(returnType.SqlTypes(factory)[0].ToString())
+ .Add(")")
+ .ToSqlString();
}
}
@@ -234,9 +239,9 @@
: base("current_timestamp", NHibernateUtil.DateTime, true)
{ }
- public override string Render(IList args, ISessionFactoryImplementor factory)
+ public override SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- return Name;
+ return new SqlString(name);
}
}
@@ -245,4 +250,4 @@
return new FirebirdDataBaseSchema(connection);
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiSubstringFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -39,26 +40,26 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count < 2 || args.Count > 3)
{
throw new QueryException("substring(): Incorrect number of parameters (expected 2 or 3, got " + args.Count + ")");
}
- StringBuilder cmd = new StringBuilder();
- cmd.Append("substring(")
- .Append(args[0])
- .Append(" from ")
- .Append(args[1]);
+ SqlStringBuilder cmd = new SqlStringBuilder();
+ cmd.Add("substring(")
+ .AddObject(args[0])
+ .Add(" from ")
+ .AddObject(args[1]);
if (args.Count > 2)
{
- cmd.Append(" for ")
- .Append(args[2]);
+ cmd.Add(" for ")
+ .AddObject(args[2]);
}
- cmd.Append(')');
- return cmd.ToString();
+ cmd.Add(")");
+ return cmd.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/AnsiTrimEmulationFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
using System.Text.RegularExpressions;
@@ -79,14 +80,14 @@
/// If only trim specification is omitted, BOTH is assumed;
/// if trim character is omitted, space is assumed
/// </remarks>
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count < 1 || args.Count > 4)
{
throw new QueryException("function takes between 1 and 4 arguments");
}
- string firstArg = (string) args[0];
+ string firstArg = args[0].ToString();
if (args.Count == 1)
{
@@ -108,7 +109,7 @@
bool leading = true; // should leading trim-characters be trimmed?
bool trailing = true; // should trailing trim-characters be trimmed?
string trimCharacter = null; // the trim-character
- string trimSource = null; // the trim-source
+ object trimSource = null; // the trim-source
// potentialTrimCharacterArgIndex = 1 assumes that a
// trim-specification has been specified. we handle the
@@ -130,11 +131,11 @@
potentialTrimCharacterArgIndex = 0;
}
- string potentialTrimCharacter = (string) args[potentialTrimCharacterArgIndex];
- if (StringHelper.EqualsCaseInsensitive("from", potentialTrimCharacter))
+ object potentialTrimCharacter = args[potentialTrimCharacterArgIndex];
+ if (StringHelper.EqualsCaseInsensitive("from", potentialTrimCharacter.ToString()))
{
trimCharacter = "' '";
- trimSource = (string) args[potentialTrimCharacterArgIndex + 1];
+ trimSource = args[potentialTrimCharacterArgIndex + 1];
}
else if (potentialTrimCharacterArgIndex + 1 >= args.Count)
{
@@ -143,14 +144,14 @@
}
else
{
- trimCharacter = potentialTrimCharacter;
- if (StringHelper.EqualsCaseInsensitive("from", (string) args[potentialTrimCharacterArgIndex + 1]))
+ trimCharacter = potentialTrimCharacter.ToString();
+ if (StringHelper.EqualsCaseInsensitive("from", args[potentialTrimCharacterArgIndex + 1].ToString()))
{
- trimSource = (string) args[potentialTrimCharacterArgIndex + 2];
+ trimSource = args[potentialTrimCharacterArgIndex + 2];
}
else
{
- trimSource = (string) args[potentialTrimCharacterArgIndex + 1];
+ trimSource = args[potentialTrimCharacterArgIndex + 1];
}
}
@@ -208,4 +209,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/CastFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.SqlTypes;
using NHibernate.Type;
@@ -34,13 +35,13 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count != 2)
{
throw new QueryException("cast() requires two arguments");
}
- string typeName = (string) args[1];
+ string typeName = args[1].ToString();
string sqlType = string.Empty;
IType hqlType = TypeFactory.HeuristicType(typeName);
if (hqlType != null)
@@ -70,7 +71,13 @@
{
throw new QueryException(string.Format("invalid Hibernate type for cast(): type {0} not found", typeName));
}
- return String.Format("cast({0} as {1})", args[0], sqlType);
+ return new SqlStringBuilder()
+ .Add("cast(")
+ .AddObject(args[0])
+ .Add(" as ")
+ .Add(sqlType)
+ .Add(")")
+ .ToSqlString();
}
#endregion
@@ -89,4 +96,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/CharIndexFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -32,7 +33,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
// TODO: QueryException if args.Count<2 (not present in H3.2)
bool threeArgs = args.Count > 2;
@@ -40,27 +41,27 @@
object orgString = args[1];
object start = threeArgs ? args[2] : null;
- StringBuilder buf = new StringBuilder();
- buf.Append("charindex(")
- .Append(pattern)
- .Append(", ");
+ SqlStringBuilder buf = new SqlStringBuilder();
+ buf.Add("charindex(")
+ .AddObject(pattern)
+ .Add(", ");
if (threeArgs)
{
- buf.Append("right(");
+ buf.Add("right(");
}
- buf.Append(orgString);
+ buf.AddObject(orgString);
if (threeArgs)
{
- buf.Append(", char_length(")
- .Append(orgString)
- .Append(")-(")
- .Append(start)
- .Append("-1))");
+ buf.Add(", char_length(")
+ .AddObject(orgString)
+ .Add(")-(")
+ .AddObject(start)
+ .Add("-1))");
}
- buf.Append(')');
- return buf.ToString();
+ buf.Add(")");
+ return buf.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/ClassicAggregateFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
using NHibernate.Util;
@@ -53,7 +54,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
//ANSI-SQL92 definition
//<general set function> ::=
@@ -69,22 +70,22 @@
{
throw new QueryException(string.Format("Aggregate {0}(): invalid argument '*'.", name));
}
- StringBuilder cmd = new StringBuilder();
- cmd.Append(name)
- .Append("(");
+ SqlStringBuilder cmd = new SqlStringBuilder();
+ cmd.Add(name)
+ .Add("(");
if (args.Count > 1)
{
- string firstArg = args[0].ToString();
- if (!StringHelper.EqualsCaseInsensitive("distinct", firstArg) &&
- !StringHelper.EqualsCaseInsensitive("all", firstArg))
+ object firstArg = args[0];
+ if (!StringHelper.EqualsCaseInsensitive("distinct", firstArg.ToString()) &&
+ !StringHelper.EqualsCaseInsensitive("all", firstArg.ToString()))
{
throw new QueryException(string.Format("Aggregate {0}(): token unknow {1}.", name, firstArg));
}
- cmd.Append(firstArg).Append(' ');
+ cmd.AddObject(firstArg).Add(" ");
}
- cmd.Append(args[args.Count - 1])
- .Append(')');
- return cmd.ToString();
+ cmd.AddObject(args[args.Count - 1])
+ .Add(")");
+ return cmd.ToSqlString();
}
#endregion
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/ISQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,5 +1,6 @@
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -38,6 +39,6 @@
/// <param name="args">List of arguments</param>
/// <param name="factory"></param>
/// <returns>SQL fragment for the fuction.</returns>
- string Render(IList args, ISessionFactoryImplementor factory);
+ SqlString Render(IList args, ISessionFactoryImplementor factory);
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/NoArgSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,5 +1,6 @@
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -9,8 +10,8 @@
/// </summary>
public class NoArgSQLFunction : ISQLFunction
{
- private readonly IType returnType = null;
- private readonly string name;
+ protected readonly IType returnType = null;
+ protected readonly string name;
private readonly bool hasParenthesesIfNoArguments;
public NoArgSQLFunction(string name, IType returnType) : this(name, returnType, true)
@@ -51,15 +52,21 @@
get { return hasParenthesesIfNoArguments; }
}
- public virtual string Render(IList args, ISessionFactoryImplementor factory)
+ public virtual SqlString Render(IList args, ISessionFactoryImplementor factory)
{
if (args.Count > 0)
{
throw new QueryException("function takes no arguments: " + name);
}
- return hasParenthesesIfNoArguments ? name + "()" : name;
+ SqlStringBuilder buf = new SqlStringBuilder(2);
+ buf.Add(name);
+ if (hasParenthesesIfNoArguments)
+ {
+ buf.Add("()");
+ }
+ return buf.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/NvlFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -31,7 +32,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
// DONE: QueryException if args.Count==0 (not present in H3.2)
if (args.Count == 0)
@@ -43,14 +44,19 @@
args.RemoveAt(lastIndex);
if (lastIndex == 0)
{
- return last.ToString();
+ return new SqlString(last);
}
object secondLast = args[lastIndex - 1];
- string nvl = "nvl(" + secondLast + ", " + last + ")";
- args[lastIndex - 1] = nvl;
+ SqlStringBuilder nvl = new SqlStringBuilder(5)
+ .Add("nvl(")
+ .AddObject(secondLast)
+ .Add(", ")
+ .AddObject(last)
+ .Add(")");
+ args[lastIndex - 1] = nvl.ToSqlString();
return Render(args, factory);
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/PositionSubstringFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -32,7 +33,7 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
// DONE: QueryException if args.Count<2 (not present in H3.2)
if (args.Count < 2)
@@ -44,35 +45,35 @@
object orgString = args[1];
object start = threeArgs ? args[2] : null;
- StringBuilder buf = new StringBuilder();
+ SqlStringBuilder buf = new SqlStringBuilder();
if (threeArgs)
{
- buf.Append('(');
+ buf.Add("(");
}
- buf.Append("position(")
- .Append(pattern)
- .Append(" in ");
+ buf.Add("position(")
+ .AddObject(pattern)
+ .Add(" in ");
if (threeArgs)
{
- buf.Append("substring(");
+ buf.Add("substring(");
}
- buf.Append(orgString);
+ buf.AddObject(orgString);
if (threeArgs)
{
- buf.Append(", ")
- .Append(start)
- .Append(')');
+ buf.Add(", ")
+ .AddObject(start)
+ .Add(")");
}
- buf.Append(')');
+ buf.Add(")");
if (threeArgs)
{
- buf.Append('+')
- .Append(start)
- .Append("-1)");
+ buf.Add("+")
+ .AddObject(start)
+ .Add("-1)");
}
- return buf.ToString();
+ return buf.ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/SQLFunctionTemplate.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -3,6 +3,7 @@
using System.Text;
using System.Text.RegularExpressions;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -98,9 +99,9 @@
/// <param name="args">args function arguments</param>
/// <param name="factory">generated SQL function call</param>
/// <returns></returns>
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- StringBuilder buf = new StringBuilder();
+ SqlStringBuilder buf = new SqlStringBuilder();
foreach (TemplateChunk tc in chunks)
{
if (tc.ArgumentIndex != InvalidArgumentIndex)
@@ -110,15 +111,22 @@
// TODO: if (arg == null) QueryException is better ?
if (arg != null)
{
- buf.Append(arg);
+ if (arg is Parameter || arg is SqlString)
+ {
+ buf.AddObject(arg);
+ }
+ else
+ {
+ buf.Add(arg.ToString());
+ }
}
}
else
{
- buf.Append(tc.Text);
+ buf.Add(tc.Text);
}
}
- return buf.ToString();
+ return buf.ToSqlString();
}
#endregion
@@ -128,4 +136,4 @@
return template;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -55,17 +56,25 @@
get { return true; }
}
- public virtual string Render(IList args, ISessionFactoryImplementor factory)
+ public virtual SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- StringBuilder buf = new StringBuilder();
- buf.Append(name)
- .Append('(');
+ SqlStringBuilder buf = new SqlStringBuilder();
+ buf.Add(name)
+ .Add("(");
for (int i = 0; i < args.Count; i++)
{
- buf.Append(args[i]);
- if (i < (args.Count - 1)) buf.Append(", ");
+ object arg = args[i];
+ if (arg is Parameter || arg is SqlString)
+ {
+ buf.AddObject(arg);
+ }
+ else
+ {
+ buf.Add(arg.ToString());
+ }
+ if (i < (args.Count - 1)) buf.Add(", ");
}
- return buf.Append(')').ToString();
+ return buf.Add(")").ToSqlString();
}
#endregion
@@ -75,4 +84,4 @@
return name;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/StandardSafeSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -39,7 +40,7 @@
this.allowedArgsCount = allowedArgsCount;
}
- public override string Render(System.Collections.IList args, NHibernate.Engine.ISessionFactoryImplementor factory)
+ public override SqlString Render(System.Collections.IList args, NHibernate.Engine.ISessionFactoryImplementor factory)
{
if (args.Count!= allowedArgsCount)
{
Modified: trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Dialect/Function/VarArgsSQLFunction.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -2,6 +2,7 @@
using System.Collections;
using System.Text;
using NHibernate.Engine;
+using NHibernate.SqlCommand;
using NHibernate.Type;
namespace NHibernate.Dialect.Function
@@ -47,17 +48,17 @@
get { return true; }
}
- public string Render(IList args, ISessionFactoryImplementor factory)
+ public SqlString Render(IList args, ISessionFactoryImplementor factory)
{
- StringBuilder buf = new StringBuilder().Append(begin);
+ SqlStringBuilder buf = new SqlStringBuilder().Add(begin);
for (int i = 0; i < args.Count; i++)
{
- buf.Append(args[i]);
- if (i < args.Count - 1) buf.Append(sep);
+ buf.AddObject(args[i]);
+ if (i < args.Count - 1) buf.Add(sep);
}
- return buf.Append(end).ToString();
+ return buf.Add(end).ToSqlString();
}
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Driver/SqlStringFormatter.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -30,6 +30,11 @@
result.Append(text);
}
+ void ISqlStringVisitor.String(SqlString sqlString)
+ {
+ result.Append(sqlString.ToString());
+ }
+
void ISqlStringVisitor.Parameter()
{
string name = formatter.GetParameterName(parameterIndex);
@@ -37,4 +42,4 @@
result.Append(name);
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/GroupByParser.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -27,6 +27,11 @@
q.AppendGroupByToken(pathExpressionParser.WhereColumn);
pathExpressionParser.AddAssociation(q);
}
+ else if (token.StartsWith(ParserHelper.HqlVariablePrefix))
+ {
+ q.AddNamedParameter(token.Substring(1));
+ q.AppendGroupByParameter();
+ }
else
{
q.AppendGroupByToken(token);
@@ -46,4 +51,4 @@
pathExpressionParser.UseThetaStyleJoin = true;
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/QueryTranslator.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -45,7 +45,7 @@
private readonly IDictionary<string, IAssociationType> uniqueKeyOwnerReferences = new Dictionary<string, IAssociationType>();
private readonly IDictionary<string, IPropertyMapping> decoratedPropertyMappings = new Dictionary<string, IPropertyMapping>();
- private readonly IList scalarSelectTokens = new ArrayList(); // contains a List of strings
+ private readonly IList<SqlString> scalarSelectTokens = new List<SqlString>();
private readonly IList<SqlString> whereTokens = new List<SqlString>();
private readonly IList<SqlString> havingTokens = new List<SqlString>();
private readonly IDictionary<string, JoinSequence> joins = new LinkedHashMap<string, JoinSequence>();
@@ -174,7 +174,9 @@
for (int i = 0; i < count; i++)
{
- sql.AddSelectFragmentString(((IQueryableCollection) persisters[i]).SelectFragment(names[i], suffixes[i]));
+ sql.AddSelectFragmentString(new SqlString(
+ ((IQueryableCollection) persisters[i]).SelectFragment(
+ (string) names[i], (string) suffixes[i])));
}
}
@@ -632,16 +634,26 @@
groupByTokens.Add(new SqlString(token));
}
+ internal void AppendGroupByParameter()
+ {
+ groupByTokens.Add(SqlString.Parameter);
+ }
+
internal void AppendScalarSelectToken(string token)
{
- scalarSelectTokens.Add(token);
+ scalarSelectTokens.Add(new SqlString(token));
}
internal void AppendScalarSelectTokens(string[] tokens)
{
- scalarSelectTokens.Add(tokens);
+ scalarSelectTokens.Add(new SqlString(tokens));
}
+ internal void AppendScalarSelectParameter()
+ {
+ scalarSelectTokens.Add(SqlString.Parameter);
+ }
+
internal void AddJoin(string name, JoinSequence joinSequence)
{
if (!joins.ContainsKey(name))
@@ -747,7 +759,7 @@
owners = null;
}
- string scalarSelect = RenderScalarSelect(); //Must be done here because of side-effect! yuck...
+ SqlString scalarSelect = RenderScalarSelect(); //Must be done here because of side-effect! yuck...
int scalarSize = scalarTypes.Count;
hasScalars = scalarTypes.Count != rtsize;
@@ -846,7 +858,7 @@
{
string name = returnedTypes[k];
string suffix = size == 1 ? String.Empty : k.ToString() + StringHelper.Underscore;
- sql.AddSelectFragmentString(persisters[k].IdentifierSelectFragment(name, suffix));
+ sql.AddSelectFragmentString(new SqlString(persisters[k].IdentifierSelectFragment(name, suffix)));
}
}
@@ -856,19 +868,19 @@
for (int k = 0; k < size; k++)
{
string suffix = (size == 1) ? String.Empty : k.ToString() + StringHelper.Underscore;
- string name = returnedTypes[k];
- sql.AddSelectFragmentString(persisters[k].PropertySelectFragment(name, suffix, false));
+ string name = (string) returnedTypes[k];
+ sql.AddSelectFragmentString(new SqlString(persisters[k].PropertySelectFragment(name, suffix, false)));
}
}
/// <summary>
/// WARNING: side-effecty
/// </summary>
- private string RenderScalarSelect()
+ private SqlString RenderScalarSelect()
{
bool isSubselect = superQuery != null;
- StringBuilder buf = new StringBuilder(20);
+ SqlStringBuilder buf = new SqlStringBuilder();
if (scalarTypes.Count == 0)
{
@@ -881,14 +893,14 @@
string[] _names = persisters[k].IdentifierColumnNames;
for (int i = 0; i < _names.Length; i++)
{
- buf.Append(returnedTypes[k]).Append(StringHelper.Dot).Append(_names[i]);
+ buf.Add(returnedTypes[k].ToString()).Add(StringHelper.Dot.ToString()).Add(_names[i]);
if (!isSubselect)
{
- buf.Append(" as ").Append(ScalarName(k, i));
+ buf.Add(" as ").Add(ScalarName(k, i));
}
if (i != _names.Length - 1 || k != size - 1)
{
- buf.Append(StringHelper.CommaSpace);
+ buf.Add(StringHelper.CommaSpace);
}
}
}
@@ -901,17 +913,17 @@
int parenCount = 0; // used to count the nesting of parentheses
for (int tokenIdx = 0; tokenIdx < scalarSelectTokens.Count; tokenIdx++)
{
- object next = scalarSelectTokens[tokenIdx];
- if (next is string)
+ SqlString next = scalarSelectTokens[tokenIdx];
+ if (next.Count == 1)
{
- string token = (string)next;
+ string token = next.ToString();
string lc = token.ToLowerInvariant();
ISQLFunction func = Factory.SQLFunctionRegistry.FindSQLFunction(lc);
if (func != null)
{
// Render the HQL function
- string renderedFunction = RenderFunctionClause(func, scalarSelectTokens, ref tokenIdx);
- buf.Append(renderedFunction);
+ SqlString renderedFunction = RenderFunctionClause(func, scalarSelectTokens, ref tokenIdx);
+ buf.Add(renderedFunction);
}
else
{
@@ -933,47 +945,47 @@
{
if (!isSubselect && parenCount == 0)
{
- buf.Append(" as ").Append(ScalarName(c++, 0));
+ buf.Add(" as ").Add(ScalarName(c++, 0));
}
}
}
- buf.Append(token);
+ buf.Add(token);
if (lc.Equals("distinct") || lc.Equals("all"))
{
- buf.Append(' ');
+ buf.Add(" ");
}
}
}
else
{
nolast = true;
- string[] tokens = (string[])next;
- for (int i = 0; i < tokens.Length; i++)
+ int i = 0;
+ foreach (object token in next.Parts)
{
- buf.Append(tokens[i]);
+ buf.AddObject(token);
if (!isSubselect)
{
- buf.Append(" as ").Append(ScalarName(c, i));
+ buf.Add(" as ").Add(ScalarName(c, i));
}
- if (i != tokens.Length - 1)
+ if (i != next.Count - 1)
{
- buf.Append(StringHelper.CommaSpace);
+ buf.Add(StringHelper.CommaSpace);
}
+ i++;
}
c++;
}
}
if (!isSubselect && !nolast)
{
- buf.Append(" as ").Append(ScalarName(c, 0));
+ buf.Add(" as ").Add(ScalarName(c++, 0));
}
}
- return buf.ToString();
+ return buf.ToSqlString();
}
- // Parameters inside function are not supported
private void RenderFunctions(IList<SqlString> tokens)
{
for (int tokenIdx = 0; tokenIdx < tokens.Count; tokenIdx++)
@@ -983,10 +995,10 @@
if (func != null)
{
int flTokenIdx = tokenIdx;
- string renderedFunction = RenderFunctionClause(func, (IList)tokens, ref flTokenIdx);
- // At this point we have the trunk that represent the function with it's parameters enclosed
- // in paren. Now all token in the tokens list can be removed from original list because they must
- // be replased with the rendered function.
+ SqlString renderedFunction = RenderFunctionClause(func, tokens, ref flTokenIdx);
+ // At this point we have the trunk that represents the function with its
+ // arguments enclosed in parens. Now all token in the tokens list will be
+ // removed from the original list and replaced with the rendered function.
for (int i = 0; i < flTokenIdx - tokenIdx; i++)
{
tokens.RemoveAt(tokenIdx + 1);
@@ -1003,30 +1015,32 @@
/// <param name="tokenIdx">The index of the list that represent the founded function.</param>
/// <returns>String trepresentation of each token.</returns>
/// <remarks>Each token can be string or SqlString </remarks>
- private StringCollection ExtractFunctionClause(IList tokens, ref int tokenIdx)
+ private IList<SqlString> ExtractFunctionClause(IList<SqlString> tokens, ref int tokenIdx)
{
- string funcName = tokens[tokenIdx].ToString();
- StringCollection functionTokens = new StringCollection();
+ SqlString funcName = tokens[tokenIdx];
+ IList<SqlString> functionTokens = new List<SqlString>();
functionTokens.Add(funcName);
tokenIdx++;
if (tokenIdx >= tokens.Count ||
!StringHelper.OpenParen.Equals(tokens[tokenIdx].ToString()))
{
- // All function with parameters have the syntax
- // <function name> <left paren> <parameters> <right paren>
+ // All function with arguments have the syntax
+ // <function name> <left paren> <arguments> <right paren>
throw new QueryException("'(' expected after function " + funcName);
}
- functionTokens.Add(StringHelper.OpenParen);
+ functionTokens.Add(new SqlString(StringHelper.OpenParen));
tokenIdx++;
int parenCount = 1;
for (; tokenIdx < tokens.Count && parenCount > 0; tokenIdx++)
{
- if (tokens[tokenIdx].ToString().StartsWith(ParserHelper.HqlVariablePrefix) || tokens[tokenIdx].ToString().Equals(StringHelper.SqlParameter))
+ if (tokens[tokenIdx].StartsWithCaseInsensitive(ParserHelper.HqlVariablePrefix) || tokens[tokenIdx].ToString().Equals(StringHelper.SqlParameter))
{
- throw new QueryException(string.Format("Parameters inside function are not supported (function '{0}').", funcName),
- new NotSupportedException());
+ functionTokens.Add(SqlString.Parameter);
}
- functionTokens.Add(tokens[tokenIdx].ToString());
+ else
+ {
+ functionTokens.Add(tokens[tokenIdx]);
+ }
if (StringHelper.OpenParen.Equals(tokens[tokenIdx].ToString()))
{
parenCount++;
@@ -1044,17 +1058,17 @@
return functionTokens;
}
- private string RenderFunctionClause(ISQLFunction func, IList tokens, ref int tokenIdx)
+ private SqlString RenderFunctionClause(ISQLFunction func, IList<SqlString> tokens, ref int tokenIdx)
{
- StringCollection functionTokens;
+ IList<SqlString> functionTokens;
if (!func.HasArguments)
{
- // The function don't work with arguments.
+ // The function doesn't work with arguments.
if (func.HasParenthesesIfNoArguments)
ExtractFunctionClause(tokens, ref tokenIdx);
- // The function render simply translate is't name for a specific dialect.
- return func.Render(CollectionHelper.EmptyList, Factory);
+ // The function render simply translate its name for a specific dialect.
+ return func.Render(new ArrayList(), Factory);
}
functionTokens = ExtractFunctionClause(tokens, ref tokenIdx);
@@ -1062,8 +1076,8 @@
if (fg == null)
fg = new CommonGrammar();
- StringCollection args = new StringCollection();
- StringBuilder argBuf = new StringBuilder(20);
+ IList args = new ArrayList();
+ SqlStringBuilder argBuf = new SqlStringBuilder();
// Extract args spliting first 2 token because are: FuncName(
// last token is ')'
// To allow expressions like arg (ex:5+5) all tokens between 'argument separator' or
@@ -1073,44 +1087,44 @@
// Ex: sum(a.Prop+10), cast(yesterday-1 as date)
for (int argIdx = 2; argIdx < functionTokens.Count - 1; argIdx++)
{
- string token = functionTokens[argIdx];
- if(fg.IsKnownArgument(token))
+ object token = functionTokens[argIdx];
+ if (fg.IsKnownArgument(token.ToString()))
{
- if (argBuf.Length > 0)
+ if (argBuf.Count > 0)
{
// end of the previous argument
- args.Add(argBuf.ToString());
- argBuf = new StringBuilder(20);
+ args.Add(argBuf.ToSqlString());
+ argBuf = new SqlStringBuilder();
}
args.Add(token);
}
- else if (fg.IsSeparator(token))
+ else if (fg.IsSeparator(token.ToString()))
{
// argument end
- if (argBuf.Length > 0)
+ if (argBuf.Count > 0)
{
- args.Add(argBuf.ToString());
- argBuf = new StringBuilder(20);
+ args.Add(argBuf.ToSqlString());
+ argBuf = new SqlStringBuilder();
}
}
else
{
- ISQLFunction nfunc = Factory.SQLFunctionRegistry.FindSQLFunction(token.ToLowerInvariant());
+ ISQLFunction nfunc = Factory.SQLFunctionRegistry.FindSQLFunction(token.ToString().ToLowerInvariant());
if (nfunc != null)
{
// the token is a nested function call
- argBuf.Append(RenderFunctionClause(nfunc, functionTokens, ref argIdx));
+ argBuf.Add(RenderFunctionClause(nfunc, functionTokens, ref argIdx));
}
else
{
// the token is a part of an argument (every thing else)
- argBuf.Append(token);
+ argBuf.AddObject(token);
}
}
}
// Add the last arg
- if (argBuf.Length > 0)
- args.Add(argBuf.ToString());
+ if (argBuf.Count > 0)
+ args.Add(argBuf.ToSqlString());
return func.Render(args, Factory);
}
Modified: trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/Hql/Classic/SelectParser.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -166,8 +166,13 @@
constantToken = true;
}
- if (constantToken)
+ if (token.StartsWith(ParserHelper.HqlVariablePrefix))
{
+ q.AddNamedParameter(token.Substring(1));
+ q.AppendScalarSelectParameter();
+ }
+ else if (constantToken)
+ {
q.AppendScalarSelectToken(token);
}
else
@@ -228,11 +233,10 @@
q.AppendScalarSelectToken(token);
q.AddSelectScalar(GetFloatingPointConstantType());
}
- else if (IsParameter(token))
+ else if (token.StartsWith(ParserHelper.HqlVariablePrefix))
{
- //q.AddNamedParameter(token.Substring(1));
- //q.AppendScalarSelectToken(token);
- throw new QueryException("parameters are not supported in SELECT.", new NotSupportedException());
+ q.AddNamedParameter(token.Substring(1));
+ q.AppendScalarSelectParameter();
}
else
throw;
@@ -244,9 +248,6 @@
#region RegExs
private static readonly Regex pathExpressionRegEx = new Regex(@"\A[A-Za-z_][A-Za-z_0-9]*[.][A-Za-z_][A-Za-z_0-9]*\z", RegexOptions.Singleline | RegexOptions.Compiled);
private static readonly Regex stringCostantRegEx = new Regex(@"\A'('{2})*([^'\r\n]*)('{2})*([^'\r\n]*)('{2})*'\z", RegexOptions.Singleline | RegexOptions.Compiled);
-
- private static readonly string paramMatcher = string.Format("\\A([{0}][A-Za-z_][A-Za-z_0-9]*)|[{1}]\\z", ParserHelper.HqlVariablePrefix, StringHelper.SqlParameter);
- private static readonly Regex parameterRegEx = new Regex(paramMatcher, RegexOptions.Singleline | RegexOptions.Compiled);
#endregion
private static bool IsPathExpression(string token)
@@ -271,11 +272,6 @@
return double.TryParse(token, NumberStyles.Number, CultureInfo.InvariantCulture, out d);
}
- private static bool IsParameter(string token)
- {
- return parameterRegEx.IsMatch(token);
- }
-
private static IType GetIntegerConstantType(string token)
{
int i;
@@ -322,4 +318,4 @@
}
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/ISqlStringVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/ISqlStringVisitor.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/ISqlStringVisitor.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -5,6 +5,7 @@
public interface ISqlStringVisitor
{
void String(string text);
+ void String(SqlString sqlString);
void Parameter();
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/QuerySelect.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -12,7 +12,7 @@
{
private readonly JoinFragment joins;
- private readonly StringBuilder selectBuilder = new StringBuilder();
+ private readonly SqlStringBuilder selectBuilder = new SqlStringBuilder();
private readonly SqlStringBuilder whereBuilder = new SqlStringBuilder();
// groupBy, orderBy, and having will for sure have no parameters.
@@ -111,9 +111,9 @@
///
/// </summary>
/// <param name="fragment"></param>
- public void AddSelectFragmentString(string fragment)
+ public void AddSelectFragmentString(SqlString fragment)
{
- if (fragment.StartsWith(","))
+ if (fragment.StartsWithCaseInsensitive(","))
{
fragment = fragment.Substring(1);
}
@@ -122,12 +122,12 @@
if (fragment.Length > 0)
{
- if (selectBuilder.Length > 0)
+ if (selectBuilder.Count > 0)
{
- selectBuilder.Append(StringHelper.CommaSpace);
+ selectBuilder.Add(StringHelper.CommaSpace);
}
- selectBuilder.Append(fragment);
+ selectBuilder.Add(fragment);
}
}
@@ -138,7 +138,7 @@
/// <param name="alias"></param>
public void AddSelectColumn(string columnName, string alias)
{
- AddSelectFragmentString(columnName + ' ' + alias);
+ AddSelectFragmentString(new SqlString(columnName + ' ' + alias));
}
/// <summary></summary>
@@ -224,12 +224,12 @@
from = from.Substring(11);
}
- builder.Add(selectBuilder.ToString())
+ builder.Add(selectBuilder.ToSqlString())
.Add(" from")
.Add(from);
SqlString part1 = joins.ToWhereFragmentString.Trim();
- SqlString part2 = whereBuilder.ToSqlString().Trim();
+ SqlString part2 = whereBuilder.ToSqlString();
bool hasPart1 = part1.Count > 0;
bool hasPart2 = part2.Count > 0;
@@ -330,4 +330,4 @@
}
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlString.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -42,7 +42,7 @@
#if DEBUG
foreach (object obj in sqlParts)
{
- Debug.Assert(obj is string || obj is Parameter);
+ Debug.Assert(obj is string || obj is SqlString || obj is Parameter);
}
#endif
this.sqlParts = sqlParts;
@@ -108,10 +108,14 @@
foreach (object part in sqlParts)
{
+ SqlString sqlStringPart = part as SqlString;
string stringPart = part as string;
-
- if (stringPart != null)
+ if (sqlStringPart != null)
{
+ sqlBuilder.Add(sqlStringPart.Compact());
+ }
+ else if (stringPart != null)
+ {
builder.Append(stringPart);
}
else
@@ -123,7 +127,7 @@
}
builder.Length = 0;
- sqlBuilder.Add((Parameter) part);
+ sqlBuilder.Add((Parameter)part);
}
}
@@ -648,10 +652,15 @@
foreach (object part in sqlParts)
{
string partString = part as string;
+ SqlString partSqlString = part as SqlString;
if (partString != null)
{
visitor.String(partString);
}
+ else if (partSqlString != null && !SqlString.Parameter.Equals(partSqlString))
+ {
+ visitor.String(partSqlString);
+ }
else
{
visitor.Parameter();
@@ -726,4 +735,4 @@
return new SubselectClauseExtractor(Compact().sqlParts).GetSqlString();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SqlStringBuilder.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/SqlStringBuilder.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/SqlStringBuilder.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -333,6 +333,11 @@
parent.Add(text);
}
+ public void String(SqlString sqlString)
+ {
+ parent.Add(sqlString);
+ }
+
public void Parameter()
{
parent.AddParameter();
@@ -344,4 +349,4 @@
sqlParts.Clear();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/HQLFunctions.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/HQLFunctions.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/HQLFunctions.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -1,3 +1,4 @@
+using System;
using System.Collections;
using NHibernate.Dialect;
using NHibernate.Dialect.Function;
@@ -17,7 +18,7 @@
static HQLFunctions()
{
notSupportedStandardFunction.Add("locate",
- new System.Type[] { typeof(MsSql2000Dialect), typeof(MsSql2005Dialect), typeof(FirebirdDialect) });
+ new System.Type[] { typeof(MsSql2000Dialect), typeof(MsSql2005Dialect), typeof(FirebirdDialect), typeof(PostgreSQLDialect) });
notSupportedStandardFunction.Add("bit_length",
new System.Type[] { typeof(MsSql2000Dialect), typeof(MsSql2005Dialect) });
notSupportedStandardFunction.Add("extract",
@@ -222,6 +223,36 @@
Animal result = (Animal) s.CreateQuery(hql).UniqueResult();
Assert.AreEqual("abcdef", result.Description);
+ hql = "from Animal a where substring(a.Description, 2, 3) = ?";
+ result = (Animal)s.CreateQuery(hql)
+ .SetParameter(0, "bcd")
+ .UniqueResult();
+ Assert.AreEqual("abcdef", result.Description);
+
+
+ hql = "from Animal a where substring(a.Description, 2, ?) = 'bcd'";
+ result = (Animal)s.CreateQuery(hql)
+ .SetParameter(0, 3)
+ .UniqueResult();
+ Assert.AreEqual("abcdef", result.Description);
+
+
+ hql = "from Animal a where substring(a.Description, ?, ?) = ?";
+ result = (Animal)s.CreateQuery(hql)
+ .SetParameter(0, 2)
+ .SetParameter(1, 3)
+ .SetParameter(2, "bcd")
+ .UniqueResult();
+ Assert.AreEqual("abcdef", result.Description);
+
+ hql = "select substring(a.Description, ?, ?) from Animal a";
+ IList results = s.CreateQuery(hql)
+ .SetParameter(0, 2)
+ .SetParameter(1, 3)
+ .List();
+ Assert.AreEqual(1, results.Count);
+ Assert.AreEqual("bcd", results[0]);
+
if (twoArgSubstringSupported)
{
hql = "from Animal a where substring(a.Description, 4) = 'def'";
@@ -560,6 +591,13 @@
result = (Animal)s.CreateQuery(hql).UniqueResult();
Assert.AreEqual("abcdef", result.Description);
+ // Rendered in WHERE using a property and named param
+ hql = "from Animal a where cast(:aParam+a.BodyWeight as Double)>0";
+ result = (Animal)s.CreateQuery(hql)
+ .SetDouble("aParam", 2D)
+ .UniqueResult();
+ Assert.AreEqual("abcdef", result.Description);
+
// Rendered in WHERE using a property and nested functions
hql = "from Animal a where cast(cast(cast(a.BodyWeight as string) as double) as int) = 1";
result = (Animal)s.CreateQuery(hql).UniqueResult();
@@ -595,6 +633,30 @@
Assert.AreEqual(1, l.Count);
Assert.AreEqual(129, l[0]);
+ // Rendered in HAVING using a property and named param (NOT SUPPORTED)
+ try
+ {
+ hql = "select cast(:aParam+a.BodyWeight as int) from Animal a group by cast(:aParam+a.BodyWeight as int) having cast(:aParam+a.BodyWeight as int)>0";
+ l = s.CreateQuery(hql).SetInt32("aParam", 10).List();
+ Assert.AreEqual(1, l.Count);
+ Assert.AreEqual(11, l[0]);
+ }
+ catch (QueryException ex)
+ {
+ if (!(ex.InnerException is NotSupportedException))
+ throw;
+ }
+ catch (ADOException ex)
+ {
+ // This test raises an exception in SQL Server because named
+ // parameters internally are always positional (@p0, @p1, etc.)
+ // and named differently hence they mismatch between GROUP BY and HAVING clauses.
+ if (!ex.InnerException.Message.Equals(
+ "Column 'Animal.BodyWeight' is invalid in the HAVING clause " +
+ "because it is not contained in either an aggregate function or the GROUP BY clause."))
+ throw;
+ }
+
// Rendered in HAVING using a property and nested functions
string castExpr = "cast(cast(cast(a.BodyWeight as string) as double) as int)";
hql = string.Format("select {0} from Animal a group by {0} having {0} = 1", castExpr);
Modified: trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SQLFunctionTemplateTest.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SQLFunctionTemplateTest.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SQLFunctionTemplateTest.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -16,19 +16,19 @@
Assert.IsTrue(ft.HasArguments);
IList args = new ArrayList();
args.Add("'abcd <'");
- Assert.AreEqual("ltrim( 'abcd <' )", ft.Render(args, factoryImpl));
+ Assert.AreEqual("ltrim( 'abcd <' )", ft.Render(args, factoryImpl).ToString());
ft = new SQLFunctionTemplate(NHibernateUtil.String, "ltrim( Az?ab )");
Assert.IsFalse(ft.HasArguments);
- Assert.AreEqual("ltrim( Az?ab )", ft.Render(args, factoryImpl));
+ Assert.AreEqual("ltrim( Az?ab )", ft.Render(args, factoryImpl).ToString());
ft = new SQLFunctionTemplate(NHibernateUtil.String, "function( ?1 )? 5:6");
Assert.IsTrue(ft.HasArguments);
- Assert.AreEqual("function( 'abcd <' )? 5:6", ft.Render(args, factoryImpl));
+ Assert.AreEqual("function( 'abcd <' )? 5:6", ft.Render(args, factoryImpl).ToString());
ft = new SQLFunctionTemplate(NHibernateUtil.String, "????????1?");
Assert.IsTrue(ft.HasArguments);
- Assert.AreEqual("???????'abcd <'?", ft.Render(args, factoryImpl));
+ Assert.AreEqual("???????'abcd <'?", ft.Render(args, factoryImpl).ToString());
}
[Test]
@@ -44,14 +44,14 @@
args.Add("'param2 ab '");
Assert.AreEqual(
"replace( replace( rtrim( replace( replace( 'param1 ', ' ', '${space}$' ), 'param2 ab ', ' ' ) ), ' ', 'param2 ab ' ), '${space}$', ' ' )",
- ft.Render(args, factoryImpl));
+ ft.Render(args, factoryImpl).ToString());
args.Clear();
ft = new SQLFunctionTemplate(NHibernateUtil.String, "?1 ?3 ?2 ?3 ?1");
args.Add(1);
args.Add(2);
args.Add(3);
- Assert.AreEqual("1 3 2 3 1", ft.Render(args, factoryImpl));
+ Assert.AreEqual("1 3 2 3 1", ft.Render(args, factoryImpl).ToString());
}
//[Test] not required
@@ -68,7 +68,7 @@
DateTime.Today.ToString(DateTimeFormatInfo.InvariantInfo),
(125.6D).ToString(NumberFormatInfo.InvariantInfo),
(0910.123456m).ToString(NumberFormatInfo.InvariantInfo));
- Assert.AreEqual(expected, ft.Render(args, factoryImpl));
+ Assert.AreEqual(expected, ft.Render(args, factoryImpl).ToString());
}
[Test]
@@ -79,13 +79,13 @@
// No Args; 2 params
ft = new SQLFunctionTemplate(NHibernateUtil.String, "func(?1,?2)");
- Assert.AreEqual("func(,)", ft.Render(args, factoryImpl));
+ Assert.AreEqual("func(,)", ft.Render(args, factoryImpl).ToString());
// Args<params
args.Clear();
ft = new SQLFunctionTemplate(NHibernateUtil.String, "func(?1,?2)");
args.Add(1);
- Assert.AreEqual("func(1,)", ft.Render(args, factoryImpl));
+ Assert.AreEqual("func(1,)", ft.Render(args, factoryImpl).ToString());
// Args>params
args.Clear();
@@ -93,7 +93,7 @@
args.Add(1);
args.Add(2);
args.Add(3);
- Assert.AreEqual("func(1,3)", ft.Render(args, factoryImpl));
+ Assert.AreEqual("func(1,3)", ft.Render(args, factoryImpl).ToString());
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SimpleFunctionsTest.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SimpleFunctionsTest.cs 2008-08-12 19:50:39 UTC (rev 3700)
+++ trunk/nhibernate/src/NHibernate.Test/HQLFunctionTest/SimpleFunctionsTest.cs 2008-08-13 14:59:18 UTC (rev 3701)
@@ -3,6 +3,7 @@
using NHibernate.Dialect.Function;
using NHibernate.SqlTypes;
using NUnit.Framework;
+using NHibernate.SqlCommand;
namespace NHibernate.Test.HQLFunctionTest
{
@@ -15,16 +16,16 @@
IList args = new ArrayList();
NoArgSQLFunction nf = new NoArgSQLFunction("noArgs", NHibernateUtil.String);
Assert.IsTrue(nf.HasParenthesesIfNoArguments);
- Assert.AreEqual("noArgs()", nf.Render(args, factoryImpl));
+ Assert.AreEqual("noArgs()", nf.Render(args, factoryImpl).ToString());
nf = new NoArgSQLFunction("noArgs", NHibernateUtil.String, false);
Assert.IsFalse(nf.HasParenthesesIfNoArguments);
- Assert.AreEqual("noArgs", nf.Render(args, factoryImpl));
+ Assert.AreEqual("noArgs", nf.Render(args, factoryImpl).ToString());
args.Add("aparam");
try
{
- string t = nf.Render(args, factoryImpl);
+ SqlString t = nf.Render(args, factoryImpl);
Assert.Fail("No exception if has argument");
}
catch (QueryException)
@@ -39,11 +40,11 @@
IList args = new ArrayList();
StandardSQLFunction sf = new StandardSQLFunction("fname");
- Assert.AreEqual("fname()", sf.Render(args, factoryImpl));
+ Assert.AreEqual("fname()", sf.Render(args, factoryImpl).ToString());
args.Add(1);
args.Add(2);
- Assert.AreEqual("fname(1, 2)", sf.Render(args, factoryImpl));
+ Assert.AreEqual("fname(1, 2)", sf.Render(args, factoryImpl).ToString());
}
[Test]
@@ -54,7 +55,7 @@
CastFunction cf = new CastFunction();
try
{
- string t = cf.Render(args, factoryImpl);
+ SqlString t = cf.Render(args, factoryImpl);
Assert.Fail("No exception if no argument");
}
catch (QueryException)
@@ -66,14 +67,14 @@
args.Add("long");
string expected =
string.Format("cast({0} as {1})", args[0], factoryImpl.Dialect.GetCastTypeName(SqlTypeFactory.Int64));
- Assert.AreEqual(expected, cf.Render(args, factoryImpl));
+ Assert.AreEqual(expected, cf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("'123'");
args.Add("NO_TYPE");
try
{
- string t = cf.Render(args, factoryImpl);
+ SqlString t = cf.Render(args, factoryImpl);
Assert.Fail("Ivalid type accepted");
}
catch (QueryException)
@@ -88,16 +89,16 @@
IList args = new ArrayList();
VarArgsSQLFunction vf = new VarArgsSQLFunction("(", " || ", ")");
- Assert.AreEqual("()", vf.Render(args, factoryImpl));
+ Assert.AreEqual("()", vf.Render(args, factoryImpl).ToString());
args.Add("va1");
- Assert.AreEqual("(va1)", vf.Render(args, factoryImpl));
+ Assert.AreEqual("(va1)", vf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("va1");
args.Add("va2");
args.Add("va3");
- Assert.AreEqual("(va1 || va2 || va3)", vf.Render(args, factoryImpl));
+ Assert.AreEqual("(va1 || va2 || va3)", vf.Render(args, factoryImpl).ToString());
}
[Test]
@@ -107,13 +108,13 @@
NvlFunction nf = new NvlFunction();
args.Add("va1");
- Assert.AreEqual("va1", nf.Render(args, factoryImpl));
+ Assert.AreEqual("va1", nf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("va1");
args.Add("va2");
args.Add("va3");
- Assert.AreEqual("nvl(va1, nvl(va2, va3))", nf.Render(args, factoryImpl));
+ Assert.AreEqual("nvl(va1, nvl(va2, va3))", nf.Render(args, factoryImpl).ToString());
}
[Test]
@@ -124,13 +125,13 @@
PositionSubstringFunction psf = new PositionSubstringFunction();
args.Add("'a'");
args.Add("va2");
- Assert.AreEqual("position('a' in va2)", psf.Render(args, factoryImpl));
+ Assert.AreEqual("position('a' in va2)", psf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("'a'");
args.Add("va2");
args.Add("2");
- Assert.AreEqual("(position('a' in substring(va2, 2))+2-1)", psf.Render(args, factoryImpl));
+ Assert.AreEqual("(position('a' in substring(va2, 2))+2-1)", psf.Render(args, factoryImpl).ToString());
}
[Test]
@@ -145,19 +146,19 @@
ClassicSumFunction csf = new ClassicSumFunction();
args.Add("va1");
- Assert.AreEqual("sum(va1)", csf.Render(args, factoryImpl));
+ Assert.AreEqual("sum(va1)", csf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("distinct");
args.Add("va2");
- Assert.AreEqual("sum(distinct va2)", csf.Render(args, factoryImpl));
+ Assert.AreEqual("sum(distinct va2)", csf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("va1");
args.Add("va2");
try
{
- string t = csf.Render(args, factoryImpl);
+ SqlString t = csf.Render(args, factoryImpl);
Assert.Fail("No exception 2 argument without <setquantifier>:" + t);
}
catch (QueryException)
@@ -175,18 +176,18 @@
ClassicCountFunction ccf = new ClassicCountFunction();
args.Add("va1");
- Assert.AreEqual("count(va1)", ccf.Render(args, factoryImpl));
+ Assert.AreEqual("count(va1)", ccf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("*");
- Assert.AreEqual("count(*)", ccf.Render(args, factoryImpl));
+ Assert.AreEqual("count(*)", ccf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("va1");
args.Add("va2");
try
{
- string t = ccf.Render(args, factoryImpl);
+ SqlString t = ccf.Render(args, factoryImpl);
Assert.Fail("No exception 2 argument without <setquantifier>:" + t);
}
catch (QueryException)
@@ -207,19 +208,19 @@
ClassicAvgFunction caf = new ClassicAvgFunction();
args.Add("va1");
- Assert.AreEqual("avg(va1)", caf.Render(args, factoryImpl));
+ Assert.AreEqual("avg(va1)", caf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("distinct");
args.Add("va2");
- Assert.AreEqual("avg(distinct va2)", caf.Render(args, factoryImpl));
+ Assert.AreEqual("avg(distinct va2)", caf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("va1");
args.Add("va2");
try
{
- string t = caf.Render(args, factoryImpl);
+ SqlString t = caf.Render(args, factoryImpl);
Assert.Fail("No exception 2 argument without <setquantifier>:" + t);
}
catch (QueryException)
@@ -235,19 +236,19 @@
ClassicAggregateFunction caf = new ClassicAggregateFunction("max", false);
args.Add("va1");
- Assert.AreEqual("max(va1)", caf.Render(args, factoryImpl));
+ Assert.AreEqual("max(va1)", caf.Render(args, factoryImpl).ToString());
args.Clear();
args.Add("d...
[truncated message content] |