These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Access 2003 - JetDriver and Hql to sql bug (join)
PostPosted: Mon Jun 18, 2007 3:01 am 
Newbie

Joined: Sun Jul 03, 2005 3:54 am
Posts: 9
Hi

I would report this to jira, but jira is not working.

My mapping is composed of 3 classes SystemUsersEntity, SystemObjectLocksEntity, SystemObjectsEntity. My mapping looks like that:

SystemUsersEntity.hbm.xml
<import class="SystemUsersDTO, Data" />
<class name="SystemUsersEntity, Data"
table="SystemUsers">
<id name="Id" column="IdSystemUser" type="Int32" unsaved-value="null">
<generator class="native" />
</id>
...
</class>

SystemObjectLocksEntity.hbm.xml
<class name="SystemObjectLocksEntity, Data"
table="SystemObjectLocks">
<id name="Id" column="IdSystemObjectLock" type="Int32" unsaved-value="null">
<generator class="native" />
</id>

...
<many-to-one name="SystemUser" column="IdSystemUser" not-null="true" outer-join="auto"></many-to-one>
<many-to-one name="SystemObject" column="IdSystemObject" not-null="true" outer-join="auto"></many-to-one>
...
</class>

SystemObjectsEntity.xbm.xml
<class name="SystemObjectsEntity, Data"
table="SystemObjects">

<id name="Id" column="IdSystemObject" type="Int32" unsaved-value="null">
<generator class="native" />
</id>

...
<set name="SystemObjectLocksSet"
cascade="all-delete-orphan"
inverse="true"
lazy="true">
<key column="IdSystemObject"/>
<one-to-many class="SystemObjectLocksEntity, Data"/>
</set>
</class>


I created the following HQL

SELECT Count(*)
FROM SystemObjectLocksEntity eentity
LEFT JOIN eentity.SystemUser SystemUser
LEFT JOIN eentity.SystemObject SystemObject

And what get's generated by hibernate is:

NHibernate:
select count(*) as x0_0_
(from SystemObjectLocks systemobje0_
left outer join SystemUsers systemuser1_ on systemobje0_.IdSystemUser=systemuser1_.IdSystemUser)
left outer join SystemObjects systemobje2_ on systemobje0_.IdSystemObject=systemobje2_.IdSystemObject

[4] 2007-06-17 22:37:10,129 [13] WARN - System.Data.OleDb.OleDbException: The SELECT statement includes a reserved word or an argument name that is misspelled or missing, or the punctuation is incorrect.

So this is a bug and the result must be:

select count(*) as x0_0_ from
(SystemObjectLocks systemobje0_ left outer join SystemUsers systemuser1_
on systemobje0_.IdSystemUser=systemuser1_.IdSystemUser)
left outer join SystemObjects systemobje2_ on systemobje0_.IdSystemObject=systemobje2_.IdSystemObject;


So left paranthesis is on a wrong place. And the paranthesis are necessary.

Note:
If there is more then one join it must be even more paranthesis.
Last part (after last join) does not have parenthesis.
First part has (n-1), where n is number of joins.

Let's see, if I would have 3 joins. It must be like this for example:

SELECT Count(*) AS x0_0_
FROM
((SystemObjectLocks AS systemobje0_ LEFT JOIN SystemUsers AS systemuser1_ ON systemobje0_.IdSystemUser = systemuser1_.IdSystemUser)
LEFT JOIN SystemObjects AS systemobje2_ ON systemobje0_.IdSystemObject = systemobje2_.IdSystemObject)
LEFT JOIN SystemObjects ON systemobje0_.IdSystemObject = SystemObjects.IdSystemObject;

Can this be fixed?

Lp
Sebastijan


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 18, 2007 4:16 pm 
Newbie

Joined: Sun Jul 03, 2005 3:54 am
Posts: 9
Hi

I looked at the code in class JetDriver.

I found the method:

Code:
private string TransformFromClause(string fromClause)
{
   string transformed;

   string[] blocks = fromClause.Split(',');
   if (blocks.Length > 1)
   {
      for (int i = 0; i < blocks.Length; i++)
      {
         string tr = TransformJoinBlock(blocks[i]);
         if (tr.IndexOf(" join ") > -1)
         {
            blocks[i] = "(select * from " + tr + ") as jetJoinAlias" + i.ToString();
         }
         else
         {
            blocks[i] = tr;
         }
      }

      transformed = string.Join(",", blocks);
   }
   else
   {
      transformed = TransformJoinBlock(blocks[0]);
   }

   return transformed;
}


So I made a few corrections, and it works now. Since it is possible, that correction should be made somewhere else....I am just submiting this code for you to check.

The new method should be:

Code:
private string TransformFromClause(string fromClause)
{
   string transformed;

  //"from ".Length
  const int fromLength = 5;
  fromClause = fromClause.Substring(fromLength, fromClause.Length - fromLength);
   string[] blocks = fromClause.Split(',');
   if (blocks.Length > 1)
   {
      for (int i = 0; i < blocks.Length; i++)
      {
         string tr = TransformJoinBlock(blocks[i]);
         if (tr.IndexOf(" join ") > -1)
         {
            blocks[i] = "(select * from " + tr + ") as jetJoinAlias" + i.ToString();
         }
         else
         {
            blocks[i] = tr;
         }
      }

      transformed = string.Join(",", blocks);
   }
   else
   {
      transformed = "from " + TransformJoinBlock(blocks[0]);
   }

   return transformed;
}


Please let me know, if you feel ok with this.

Lp
Pistotnik


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 18, 2007 7:31 pm 
Regular
Regular

Joined: Sun Jan 21, 2007 4:33 pm
Posts: 65
Jet/Access doesn't do outer joins -- or am I missing something?


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 18, 2007 7:46 pm 
Regular
Regular

Joined: Fri Jan 27, 2006 2:32 pm
Posts: 102
Location: California, USA
Gortok wrote:
Jet/Access doesn't do outer joins -- or am I missing something?


I think you're missing something. Jet does indeed do outer joins:

Here's a simple example:

Code:
Select TableA.TextA, TableB.TextB From TableA LEFT JOIN TableB on TableA.RowA = TableB.RowA


This will give all rows from TableA and any rows from TableB where the RowA columns match.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jun 18, 2007 8:16 pm 
Regular
Regular

Joined: Sun Jan 21, 2007 4:33 pm
Posts: 65
pelton wrote:
Gortok wrote:
Jet/Access doesn't do outer joins -- or am I missing something?


I think you're missing something. Jet does indeed do outer joins:

Here's a simple example:

Code:
Select TableA.TextA, TableB.TextB From TableA LEFT JOIN TableB on TableA.RowA = TableB.RowA


This will give all rows from TableA and any rows from TableB where the RowA columns match.


That's not an outer join. That's an innerleft join.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 19, 2007 4:05 am 
Newbie

Joined: Sun Jul 03, 2005 3:54 am
Posts: 9
Ja...this bug is already reported....but jira did not work, so I coud not see.

http://jira.nhibernate.org/browse/NH-1006

Sory...

Lp
Sebastijan


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.