Skip to content

Commit

Permalink
New Oracle12c dialect
Browse files Browse the repository at this point in the history
Pagination done using offset/fetch
  • Loading branch information
lnu committed Mar 17, 2015
1 parent b5e0607 commit 6d17e88
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 0 deletions.
95 changes: 95 additions & 0 deletions src/NHibernate.Test/DialectTest/Oracle12cDialectFixture.cs
@@ -0,0 +1,95 @@
using NHibernate.Dialect;
using NHibernate.SqlCommand;
using NUnit.Framework;

namespace NHibernate.Test.DialectTest
{
[TestFixture]
public class oracle12cDialectFixture
{
[Test]
public void GetLimitString()
{
var d = new Oracle12cDialect();

SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c.Rating as Rating2_19_0_, c.Last_Name as Last_Name3_19_0, c.First_Name as First_Name4_19_0 from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"select distinct c.Contact_Id as Contact1_19_0_, c.Rating as Rating2_19_0_, c.Last_Name as Last_Name3_19_0, c.First_Name as First_Name4_19_0 from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT fish.id FROM fish"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT fish.id FROM fish OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id FROM fish fish_"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT DISTINCT fish_.id FROM fish fish_ OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_ OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT * FROM fish ORDER BY name OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT fish.id, fish.name FROM fish ORDER BY name DESC"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT fish.id, fish.name FROM fish ORDER BY name DESC OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT * FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t ORDER BY name DESC"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT * FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t ORDER BY name DESC OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT * FROM fish WHERE scales = ", Parameter.Placeholder), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT * FROM fish WHERE scales = ? OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());

str = d.GetLimitString(new SqlString("SELECT f.Type, COUNT(DISTINCT f.Name) AS Name FROM Fish f GROUP BY f.Type ORDER BY COUNT(DISTINCT f.Name)"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT f.Type, COUNT(DISTINCT f.Name) AS Name FROM Fish f GROUP BY f.Type ORDER BY COUNT(DISTINCT f.Name) OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());
}

[Test]
public void GetLimitStringWithInnerOrder()
{
var d = new Oracle12cDialect();

var str = d.GetLimitString(new SqlString("SELECT * FROM A LEFT JOIN (SELECT top 7 * FROM B ORDER BY name) AS B on A.Name = B.Name"), new SqlString("111"), new SqlString("222"));
Assert.AreEqual(
"SELECT * FROM A LEFT JOIN (SELECT top 7 * FROM B ORDER BY name) AS B on A.Name = B.Name OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
str.ToString());
}

[Test]
public void OnlyOffsetLimit()
{
var d = new Oracle12cDialect();

SqlString str = d.GetLimitString(new SqlString("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name"), null, new SqlString("10"));
Assert.That(str.ToString(), Is.EqualTo("select distinct c.Contact_Id as Contact1_19_0_, c._Rating as Rating2_19_0_ from dbo.Contact c where COALESCE(c.Rating, 0) > 0 order by c.Rating desc , c.Last_Name , c.First_Name FETCH FIRST 10 ROWS ONLY"));
}

[Test]
public void GetLimitStringWithSqlComments()
{
var d = new Oracle12cDialect();
var limitSqlQuery = d.GetLimitString(new SqlString(" /* criteria query */ SELECT p from lcdtm"), null, new SqlString("2"));
Assert.That(limitSqlQuery, Is.Not.Null);
Assert.That(limitSqlQuery.ToString(), Is.EqualTo(" /* criteria query */ SELECT p from lcdtm FETCH FIRST 2 ROWS ONLY"));
}
}
}
1 change: 1 addition & 0 deletions src/NHibernate.Test/NHibernate.Test.csproj
Expand Up @@ -230,6 +230,7 @@
<Compile Include="DialectTest\FunctionTests\SubstringSupportFixture.cs" />
<Compile Include="DialectTest\FunctionTests\SequenceSupportFixture.cs" />
<Compile Include="DialectTest\Ingres9DialectFixture.cs" />
<Compile Include="DialectTest\Oracle12cDialectFixture.cs" />
<Compile Include="DialectTest\MsSql2012DialectFixture.cs" />
<Compile Include="DialectTest\LockHintAppenderFixture.cs" />
<Compile Include="DialectTest\MsSqlCe40DialectFixture.cs" />
Expand Down
42 changes: 42 additions & 0 deletions src/NHibernate/Dialect/Oracle12cDialect.cs
@@ -0,0 +1,42 @@
using NHibernate.SqlCommand;

namespace NHibernate.Dialect
{
/// <summary>
/// A dialect specifically for use with Oracle 10g.
/// </summary>
/// <remarks>
/// The main difference between this dialect and <see cref="Oracle12cDialect"/>
/// is the use of "ANSI join syntax" here...
/// </remarks>
public class Oracle12cDialect : Oracle10gDialect
{
/// <summary>
/// Oracle 12c supports a query statement that provides <c>LIMIT</c>
/// functionality with an offset.
/// </summary>
/// <value><c>false</c></value>
public override bool UseMaxForLimit
{
get { return false; }
}

public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
{
var result = new SqlStringBuilder(querySqlString);

if (offset != null)
{
result.Add(" OFFSET ");
result.Add(offset).Add(" ROWS");
}

if (limit != null)
{
result.Add(" FETCH FIRST ").Add(limit).Add(" ROWS ONLY");
}

return result.ToSqlString();
}
}
}
1 change: 1 addition & 0 deletions src/NHibernate/NHibernate.csproj
Expand Up @@ -158,6 +158,7 @@
<Compile Include="Dialect\MySQL5InnoDBDialect.cs" />
<Compile Include="Dialect\MySQLDialect.cs" />
<Compile Include="Dialect\BitwiseNativeOperation.cs" />
<Compile Include="Dialect\Oracle12cDialect.cs" />
<Compile Include="Dialect\PostgreSQLDialect.cs" />
<Compile Include="Dialect\Schema\PostgreSQLMetadata.cs" />
<Compile Include="Dialect\Schema\SchemaHelper.cs" />
Expand Down

0 comments on commit 6d17e88

Please sign in to comment.