Skip to content

Commit 6d17e88

Browse files
committed
New Oracle12c dialect
Pagination done using offset/fetch
1 parent b5e0607 commit 6d17e88

File tree

4 files changed

+139
-0
lines changed

4 files changed

+139
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
using NHibernate.Dialect;
2+
using NHibernate.SqlCommand;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.DialectTest
6+
{
7+
[TestFixture]
8+
public class oracle12cDialectFixture
9+
{
10+
[Test]
11+
public void GetLimitString()
12+
{
13+
var d = new Oracle12cDialect();
14+
15+
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"));
16+
Assert.AreEqual(
17+
"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",
18+
str.ToString());
19+
20+
str = d.GetLimitString(new SqlString("SELECT fish.id FROM fish"), new SqlString("111"), new SqlString("222"));
21+
Assert.AreEqual(
22+
"SELECT fish.id FROM fish OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
23+
str.ToString());
24+
25+
str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id FROM fish fish_"), new SqlString("111"), new SqlString("222"));
26+
Assert.AreEqual(
27+
"SELECT DISTINCT fish_.id FROM fish fish_ OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
28+
str.ToString());
29+
30+
str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_"), new SqlString("111"), new SqlString("222"));
31+
Assert.AreEqual(
32+
"SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_ OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
33+
str.ToString());
34+
35+
str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), new SqlString("111"), new SqlString("222"));
36+
Assert.AreEqual(
37+
"SELECT * FROM fish ORDER BY name OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
38+
str.ToString());
39+
40+
str = d.GetLimitString(new SqlString("SELECT fish.id, fish.name FROM fish ORDER BY name DESC"), new SqlString("111"), new SqlString("222"));
41+
Assert.AreEqual(
42+
"SELECT fish.id, fish.name FROM fish ORDER BY name DESC OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
43+
str.ToString());
44+
45+
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"));
46+
Assert.AreEqual(
47+
"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",
48+
str.ToString());
49+
50+
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"));
51+
Assert.AreEqual(
52+
"SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
53+
str.ToString());
54+
55+
str = d.GetLimitString(new SqlString("SELECT * FROM fish WHERE scales = ", Parameter.Placeholder), new SqlString("111"), new SqlString("222"));
56+
Assert.AreEqual(
57+
"SELECT * FROM fish WHERE scales = ? OFFSET 111 ROWS FETCH FIRST 222 ROWS ONLY",
58+
str.ToString());
59+
60+
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"));
61+
Assert.AreEqual(
62+
"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",
63+
str.ToString());
64+
}
65+
66+
[Test]
67+
public void GetLimitStringWithInnerOrder()
68+
{
69+
var d = new Oracle12cDialect();
70+
71+
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"));
72+
Assert.AreEqual(
73+
"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",
74+
str.ToString());
75+
}
76+
77+
[Test]
78+
public void OnlyOffsetLimit()
79+
{
80+
var d = new Oracle12cDialect();
81+
82+
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"));
83+
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"));
84+
}
85+
86+
[Test]
87+
public void GetLimitStringWithSqlComments()
88+
{
89+
var d = new Oracle12cDialect();
90+
var limitSqlQuery = d.GetLimitString(new SqlString(" /* criteria query */ SELECT p from lcdtm"), null, new SqlString("2"));
91+
Assert.That(limitSqlQuery, Is.Not.Null);
92+
Assert.That(limitSqlQuery.ToString(), Is.EqualTo(" /* criteria query */ SELECT p from lcdtm FETCH FIRST 2 ROWS ONLY"));
93+
}
94+
}
95+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@
230230
<Compile Include="DialectTest\FunctionTests\SubstringSupportFixture.cs" />
231231
<Compile Include="DialectTest\FunctionTests\SequenceSupportFixture.cs" />
232232
<Compile Include="DialectTest\Ingres9DialectFixture.cs" />
233+
<Compile Include="DialectTest\Oracle12cDialectFixture.cs" />
233234
<Compile Include="DialectTest\MsSql2012DialectFixture.cs" />
234235
<Compile Include="DialectTest\LockHintAppenderFixture.cs" />
235236
<Compile Include="DialectTest\MsSqlCe40DialectFixture.cs" />
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using NHibernate.SqlCommand;
2+
3+
namespace NHibernate.Dialect
4+
{
5+
/// <summary>
6+
/// A dialect specifically for use with Oracle 10g.
7+
/// </summary>
8+
/// <remarks>
9+
/// The main difference between this dialect and <see cref="Oracle12cDialect"/>
10+
/// is the use of "ANSI join syntax" here...
11+
/// </remarks>
12+
public class Oracle12cDialect : Oracle10gDialect
13+
{
14+
/// <summary>
15+
/// Oracle 12c supports a query statement that provides <c>LIMIT</c>
16+
/// functionality with an offset.
17+
/// </summary>
18+
/// <value><c>false</c></value>
19+
public override bool UseMaxForLimit
20+
{
21+
get { return false; }
22+
}
23+
24+
public override SqlString GetLimitString(SqlString querySqlString, SqlString offset, SqlString limit)
25+
{
26+
var result = new SqlStringBuilder(querySqlString);
27+
28+
if (offset != null)
29+
{
30+
result.Add(" OFFSET ");
31+
result.Add(offset).Add(" ROWS");
32+
}
33+
34+
if (limit != null)
35+
{
36+
result.Add(" FETCH FIRST ").Add(limit).Add(" ROWS ONLY");
37+
}
38+
39+
return result.ToSqlString();
40+
}
41+
}
42+
}

src/NHibernate/NHibernate.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@
158158
<Compile Include="Dialect\MySQL5InnoDBDialect.cs" />
159159
<Compile Include="Dialect\MySQLDialect.cs" />
160160
<Compile Include="Dialect\BitwiseNativeOperation.cs" />
161+
<Compile Include="Dialect\Oracle12cDialect.cs" />
161162
<Compile Include="Dialect\PostgreSQLDialect.cs" />
162163
<Compile Include="Dialect\Schema\PostgreSQLMetadata.cs" />
163164
<Compile Include="Dialect\Schema\SchemaHelper.cs" />

0 commit comments

Comments
 (0)