Title: Message
Question:  Given a Queryable and a property name where the property refers to a relationship to another class (i.e. the property is a one-to-one, many-to-one):
(a) How do you tell what the cardinality of the relationship is (i.e. how do you know which table the foriegn key lives in)?
(b) How do you get the foreign key column name for the relationship?
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Joshua Davis
Sent: Tuesday, December 09, 2003 6:23 AM
To: [EMAIL PROTECTED]
Subject: RE: [Hibernate] AST parser for HQL

The following is an example of the output from each phase when an 'implied join' is processed.  The hibernate mapping is enclosed.
 
Notes:
1) The 'booleanExpr=>' sub-tree is the resulting tree *after* the analyzer has added any theta-style join clauses.
2) It does not yet add the nodes to the 'FROM' part of the tree, but I'm working on that.
3) I wasn't able to find an API call to get the foreign key column name in the 'origin' part of the join (in this case, the alias 'foo'), hence the {highy-bogus-column-name} token.   ;)  Any hints?
 
HQL =>from eg.Foo foo
where foo.bar.name='Farrels'<=
--- HQL AST ---
 \-'query' [QUERY]
    +-'from' [FROM]
    |  +-'.' [DOT]
    |  |  +-'eg' [IDENT]
    |  |  \-'Foo' [IDENT]
    |  \-'foo' [ALIAS]
    \-'where' [WHERE]
       \-'=' [EQ]
          +-'.' [DOT]
          |  +-'.' [DOT]
          |  |  +-'foo' [IDENT]
          |  |  \-'bar' [IDENT]
          |  \-'name' [IDENT]
          \-''Farrels'' [QUOTED_STRING]
Dec 9, 2003 6:10:00 AM net.sf.hibernate.hql.parser.HqlSqlWalker createColumnRefNode
INFO: Discovered an implied join from eg.Foo.bar to eg.Bar
booleanExpr=>
 \-'AND' [AND]
    +-'=' [EQ]
    |  +-'foo.{highly-bogus-column-name}bar' [COLUMN_REF]
    |  \-'bar1_.ID' [COLUMN_REF]
    \-'=' [EQ]
       +-'bar1_.NAME' [COLUMN_REF]
       \-''Farrels'' [QUOTED_STRING]
--- SQL AST ---
 \-'select' [SELECT]
    +-'from' [FROM]
    |  \-'EG_FOOS AS foo' [TABLE_NAME]
    \-'where' [WHERE]
       \-'AND' [AND]
          +-'=' [EQ]
          |  +-'foo.{highly-bogus-column-name}bar' [COLUMN_REF]
          |  \-'bar1_.ID' [COLUMN_REF]
          \-'=' [EQ]
             +-'bar1_.NAME' [COLUMN_REF]
             \-''Farrels'' [QUOTED_STRING]
SQL =>SELECT * FROM EG_FOOS AS foo WHERE foo.{highly-bogus-column-name}bar = bar1_.ID AND bar1_.NAME = 'Farrels'<=
 
 

HQL =>from eg.Foo foo, eg.Bar bar where foo.bar.name='Farrels'<=
--- HQL AST ---
 \-'query' [QUERY]
    +-'from' [FROM]
    |  +-'.' [DOT]
    |  |  +-'eg' [IDENT]
    |  |  \-'Foo' [IDENT]
    |  +-'foo' [ALIAS]
    |  +-'.' [DOT]
    |  |  +-'eg' [IDENT]
    |  |  \-'Bar' [IDENT]
    |  \-'bar' [ALIAS]
    \-'where' [WHERE]
       \-'=' [EQ]
          +-'.' [DOT]
          |  +-'.' [DOT]
          |  |  +-'foo' [IDENT]
          |  |  \-'bar' [IDENT]
          |  \-'name' [IDENT]
          \-''Farrels'' [QUOTED_STRING]
booleanExpr=>
Dec 9, 2003 6:10:00 AM net.sf.hibernate.hql.parser.HqlSqlWalker createColumnRefNode
INFO: Discovered an implied join from eg.Foo.bar to eg.Bar
 \-'AND' [AND]
    +-'=' [EQ]
    |  +-'foo.{highly-bogus-column-name}bar' [COLUMN_REF]
    |  \-'bar.ID' [COLUMN_REF]
    \-'=' [EQ]
       +-'foo.NAME' [COLUMN_REF]
       \-''Farrels'' [QUOTED_STRING]
--- SQL AST ---
 \-'select' [SELECT]
    +-'from' [FROM]
    |  +-'EG_FOOS AS foo' [TABLE_NAME]
    |  \-'EG_BARS AS bar' [TABLE_NAME]
    \-'where' [WHERE]
       \-'AND' [AND]
          +-'=' [EQ]
          |  +-'foo.{highly-bogus-column-name}bar' [COLUMN_REF]
          |  \-'bar.ID' [COLUMN_REF]
          \-'=' [EQ]
             +-'foo.NAME' [COLUMN_REF]
             \-''Farrels'' [QUOTED_STRING]
SQL =>SELECT * FROM EG_FOOS AS foo, EG_BARS AS bar WHERE foo.{highly-bogus-column-name}bar = bar.ID AND foo.NAME = 'Farrels'<=
-----Original Message-----
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Joshua Davis
Sent: Monday, December 08, 2003 11:14 PM
To: [EMAIL PROTECTED]
Cc: 'Joshua Davis'
Subject: [Hibernate] AST parser for HQL

Hibernate programmers,
 
I've made some progress with the HQL parser, so here's an update:
 
Design decisions:
1) Use ANTLR to generate the parser.  It has a compatible Open Source licence, and adds only one new library dependency.
2) Use a three phase design:  parse/analyze/generate code - This is a very typical modular compiler design.  The parse phase is implemented as a stream parser, the analysis phase is implemented as a tree parser (tree transform, actually), and the code generation phase is a tree parser that produces an SQL stream.
3) Use the ANTLR generated parsers as base classes, implementing the main semantic / syntax analysis functions in derived classes.  This keeps the grammar files smaller, and alows me to use my favorite Java IDE to write the analysis code.
 
So, what's been done so far?
 
* An HQL grammar / parser which sucessfully parses most of the examples in the Hibernate HQL doco.  A few additional features have been added, as well as a unit test that exercises this phase.
 
* An HQL AST analyzer, which converts the HQL AST into an intermediate, SQL (ish) AST.  This is implemented as a tree parser which normalizes the HQL AST and binds the HQL AST elements to the appropriate Hibernate mapping API objects (e.g. Queryable, etc.).
 
* A very simplistic SQL generator, which walks the intermediate tree and produces an SQL stream.   This is primarly for testing, although it might come in handy later on when integrating all this into Hibernate.
 
* Some initial 'implied join' examples.
 
What's next?
 
* Get implied joins (and 'fake' AST generation to work).
 
* Utilize more of the existing Hibernate API for mappings.

Reply via email to