Permalink
Browse files

NH-3784, NH-3785 Change the way collection filtering is handled.

1) Move conversion of filter-implied from elements to separate preprocessing stage.

This removes confusing idiom of mutating input AST during AST walking with Antlr Tree Parser.

2) Disallow DML queries in collection filters.

3) Do not apply collection filters to inner subqueries.

Also remove some old hacks from Antlr grammars.
  • Loading branch information...
1 parent c13f70d commit db0d6e86a0d58b22701b9fd8ef2af88c3fbf97c9 @dmitryvk dmitryvk committed May 3, 2015
View
@@ -11,3 +11,4 @@ current-test-configuration
# This will be copied from the build directory to the lib directory in order
# to satisfy later build steps. But it should not be committed.
NHibernate.dll
+TestResult.xml
@@ -0,0 +1,159 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Antlr.Runtime;
+using NHibernate.Hql.Ast.ANTLR;
+using NUnit.Framework;
+using System.Collections;
+using NHibernate.DomainModel;
+
+namespace NHibernate.Test.CollectionFilterTest
+{
+ [TestFixture]
+ public class CollectionFilterQueriesTest : TestCase
+ {
+ protected override IList Mappings
+ {
+ get
+ {
+ return new string[] { "One.hbm.xml", "Many.hbm.xml" };
+ }
+ }
+
+ private One one;
+
+ protected override void OnSetUp()
+ {
+ base.OnSetUp();
+
+ // create the objects to search on
+ one = new One();
+ one.X = 20;
+ one.Manies = new HashSet<Many>();
+
+ Many many1 = new Many();
+ many1.X = 10;
+ many1.One = one;
+ one.Manies.Add( many1 );
+
+ Many many2 = new Many();
+ many2.X = 20;
+ many2.One = one;
+ one.Manies.Add( many2 );
+
+ using( ISession s = OpenSession() )
+ using( ITransaction t = s.BeginTransaction() )
+ {
+ s.Save( one );
+ s.Save( many1 );
+ s.Save( many2 );
+ t.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using( ISession session = OpenSession() )
+ using( ITransaction tx = session.BeginTransaction() )
+ {
+ session.Delete( "from Many" );
+ session.Delete( "from One" );
+ tx.Commit();
+ }
+ base.OnTearDown();
+ }
+
+ [Test]
+ public void UpdateShouldBeDisallowed()
+ {
+ using (ISession s = OpenSession())
+ using (ITransaction t = s.BeginTransaction())
+ {
+ One one2 = (One)s.CreateQuery("from One").UniqueResult();
+
+ Assert.Throws<QuerySyntaxException>(() =>
+ {
+ s.CreateFilter(one2.Manies, "update Many set X = 1")
+ .ExecuteUpdate();
+ // Collection filtering disallows DML queries
+ });
+
+ t.Rollback();
+ }
+ }
+
+ [Test]
+ public void DeleteShouldBeDisallowed()
+ {
+ using (ISession s = OpenSession())
+ using (ITransaction t = s.BeginTransaction())
+ {
+ One one2 = (One)s.CreateQuery("from One").UniqueResult();
+
+ Assert.Throws<QuerySyntaxException>(() =>
+ {
+ s.CreateFilter(one2.Manies, "delete from Many")
+ .ExecuteUpdate();
+ // Collection filtering disallows DML queries
+ });
+
+ t.Rollback();
+ }
+ }
+
+ [Test]
+ public void InsertShouldBeDisallowed()
+ {
+ using (ISession s = OpenSession())
+ using (ITransaction t = s.BeginTransaction())
+ {
+ One one2 = (One)s.CreateQuery("from One").UniqueResult();
+
+ Assert.Throws<QuerySyntaxException>(() =>
+ {
+ s.CreateFilter(one2.Manies, "insert into Many (X) select t0.X from Many t0")
+ .ExecuteUpdate();
+ // Collection filtering disallows DML queries
+ });
+
+ t.Rollback();
+ }
+ }
+
+ [Test]
+ public void InnerSubqueryShouldNotBeFiltered()
+ {
+ using (ISession s = OpenSession())
+ using (ITransaction t = s.BeginTransaction())
+ {
+ One one2 = (One)s.CreateQuery("from One").UniqueResult();
+
+ s.CreateFilter(one2.Manies, "where this.X in (select t0.X from Many t0)")
+ .List();
+ // Filter should only affect outer query, not inner
+
+ t.Rollback();
+ }
+ }
+
+ [Test]
+ public void InnerSubqueryMustHaveFromClause()
+ {
+ using (ISession s = OpenSession())
+ using (ITransaction t = s.BeginTransaction())
+ {
+ One one2 = (One)s.CreateQuery("from One").UniqueResult();
+
+ Assert.Throws<QuerySyntaxException>(() =>
+ {
+ s.CreateFilter(one2.Manies, "where this.X in (select X)")
+ .List();
+ // Inner query for filter query should have FROM clause
+ });
+
+ t.Rollback();
+ }
+ }
+ }
+}
@@ -178,6 +178,7 @@
<Compile Include="Classic\LifecycleFixture.cs" />
<Compile Include="Classic\ValidatableFixture.cs" />
<Compile Include="Classic\Video.cs" />
+ <Compile Include="CollectionFilterTest\CollectionFilterQueriesTest.cs" />
<Compile Include="CollectionTest\A.cs" />
<Compile Include="CollectionTest\IdBagFixture.cs" />
<Compile Include="CollectionTest\NullableValueTypeElementMapFixture.cs" />
Oops, something went wrong.

0 comments on commit db0d6e8

Please sign in to comment.