Author: steve.ebersole(a)jboss.com
Date: 2009-01-06 15:11:13 -0500 (Tue, 06 Jan 2009)
New Revision: 15747
Added:
core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/resolve/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/resolve/path/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
Removed:
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/
Modified:
core/branches/SQL_GEN_REDESIGN/pom.xml
core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g
core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java
core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties
Log:
HHH-2407 : HQL translation rework ->
HHH-3687 : parse (phase1)
HHH-3688 : normalize (phase2)
Modified: core/branches/SQL_GEN_REDESIGN/pom.xml
===================================================================
--- core/branches/SQL_GEN_REDESIGN/pom.xml 2009-01-06 17:14:14 UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/pom.xml 2009-01-06 20:11:13 UTC (rev 15747)
@@ -185,14 +185,34 @@
<version>${antlrPluginVersion}</version>
<configuration>
<traceParser>true</traceParser>
+ <traceTreeParser>true</traceTreeParser>
<grammarDefs>
<grammar>
<name>sql/common.g</name>
</grammar>
<grammar>
<name>hql/parse.g</name>
- <glib>sql/common.g</glib>
</grammar>
+ <grammar>
+ <name>hql/normalize.g</name>
+ </grammar>
+ <grammar>
+ <name>order/parse.g</name>
+ </grammar>
+ <grammar>
+ <name>order/render.g</name>
+ </grammar>
+ <!-- temporary -->
+ <grammar>
+ <name>hql.g</name>
+ </grammar>
+ <grammar>
+ <name>hql-sql.g</name>
+ </grammar>
+ <grammar>
+ <name>sql-gen.g</name>
+ </grammar>
+ <!-- / temporary -->
</grammarDefs>
</configuration>
<executions>
@@ -208,6 +228,6 @@
</build>
<properties>
- <antlrPluginVersion>2.1</antlrPluginVersion>
+ <antlrPluginVersion>2.2-SNAPSHOT</antlrPluginVersion>
</properties>
</project>
Copied: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g (from rev 15693,
core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/resolve.g)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g
(rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g 2009-01-06 20:11:13 UTC
(rev 15747)
@@ -0,0 +1,1099 @@
+header {
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ * Portions of SQL grammar parsing copyright (C) 2003 by Lubos Vnuk. All rights
+ * reserved. These portions are distributed under license by Red Hat Middleware
+ * LLC and are covered by the above LGPL notice. If you redistribute this material,
+ * with or without modification, you must preserve this copyright notice in its
+ * entirety.
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.DetailedSemanticException;
+}
+
+/**
+ * An Antlr tree parser for "resolving" or "normalizing" an HQL
syntax AST. This
+ * parser provides the vast majority of the semantic analysis of the HQL AST.
+ * <p/>
+ * Both "resolving" and "normalizing" here seek a single goal of
building a
+ * dis-ambiguated, generic query AST.
+ * <p/>
+ * The act of resolving is essentially the process of simplifying complex node
+ * structures into atomic components based on contextual information (aka, the
+ * current parser state). The main thrust of this process is breaking down
+ * dot-structures (a series of DOT INDET pairs) into <ul>
+ * <li>a series of "implicit" join structures injected into the from
clause tree</li>
+ * <li>a simple structure representing the "meaning" of the
"leaf" of said dot-structure</li>
+ * </ul>
+ * <p/>
+ * The act of normalizing essentially refers to the process of dis-ambiguating
+ * node structures based on their context and creating a unified AST
+ * representation for different ways to express the same "idea". An example of
this
+ * is normalizing implicit join dot-structures into a structure akin to its explicit
+ * join corollary.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+class GeneratedHqlNormalizer extends TreeParser;
+
+options {
+ importVocab = HqlParse;
+ exportVocab = HqlNormalize;
+ buildAST = true;
+}
+
+tokens {
+ PROPERTY_REF;
+}
+
+
+// -- Declarations --
+{
+ private static Logger log = LoggerFactory.getLogger( GeneratedHqlNormalizer.class );
+
+ private int ordinalParamCount = 0;
+
+
+ // persister reference related actions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected AST normalizeEntityName(AST node) throws SemanticException {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected AST normalizeAlias(AST node) {
+ if ( node != null ) {
+ return node;
+ }
+ String syntheticAlias = buildUniqueImplicitAlias();
+ return #([ALIAS,syntheticAlias]);
+ }
+
+ protected String buildUniqueImplicitAlias() {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected void registerPersisterReference(AST reference) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected boolean isPersisterReferenceAlias(AST alias) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected boolean isCollectionPersisterReferenceAlias(AST alias) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+
+ // property reference related actions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected final boolean isUnqualifiedPropertyReference(AST property) {
+ return locateOwningPersisterAlias( property ) != null;
+ }
+
+ protected final AST normalizeUnqualifiedPropertyReference(AST property) {
+ return #( [PROPERTY_REF], owningPersisterAliasReference( property ), property );
+ }
+
+ protected final AST owningPersisterAliasReference(AST property) {
+ return #( [ALIAS_REF,locateOwningPersisterAlias(property)] );
+ }
+
+ protected String locateOwningPersisterAlias(AST property) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+
+ // path normalization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected AST normalizeQualifiedRoot(AST alias) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected AST normalizeUnqualifiedRoot(AST alias) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected AST normalizeIndexedRoot(AST alias) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected AST normalizePropertyPathIntermediary(AST source, AST propertyNameNode) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+ protected AST normalizePropertyPathTerminus(AST source, AST propertyNameNode) {
+ throw new UnsupportedOperationException( "must be overridden!" );
+ }
+
+
+ // Statement node BEGIN/END handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void pushStatement(AST statementNode) {
+ }
+
+ protected void popStatement() {
+ }
+
+
+ // property-path context pushing/popping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void pushFromClausePropertyPathContext(AST joinType, AST fetch, AST alias, AST
propertyFetch) {
+ }
+
+ protected void popFromClausePropertyPathContext() {
+ }
+
+ protected void pushSelectClausePropertyPathContext() {
+ }
+
+ protected void popSelectClausePropertyPathContext() {
+ }
+
+ protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+ }
+
+ protected void popOnFragmentPropertyPathContext() {
+ }
+
+ protected void pushWithFragmentPropertyPathContext(AST rhsPersisterReference) {
+ }
+
+ protected void popWithFragmentPropertyPathContext() {
+ }
+
+
+
+
+ // function processing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void startingFunction() {
+ }
+
+ protected void endingFunction() {
+ }
+
+
+
+
+ protected void registerSelectItem(AST selectItem) {
+ }
+
+
+
+
+
+ protected AST resolveAlias(AST alias) {
+ return alias;
+ }
+
+ /**
+ * Validate the operands to the index operator '[]'. Specifically, the
left-hand operand should be a reference
+ * to some form of indexed collection (map or list) and the right-hand operand should
be a value expression
+ * whose type is the same as the indexed collection's index values.
+ *
+ * @param collectionPropertyReference The left-hand operand. Should resolve to an
indexed collection
+ * @param selector the right-hand operand. Should resolve to a value type compatible
with the collection's
+ * index type.
+ */
+ protected void validateIndexOperationOperands(AST collectionPropertyReference, AST
selector) {
+ }
+
+
+ // persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected AST buildEntityPersisterReference(AST entityName, AST alias, AST
propertyFetch) {
+ return entityName;
+ }
+
+ protected AST buildAdHocJoinNode(AST persisterReference, AST joinType, AST withFragment)
{
+ return persisterReference;
+ }
+
+ protected void applyWithFragment(AST withFragment) {
+ }
+
+ protected void injectSelectAlias( AST selectExpression, AST alias) {
+ }
+
+ protected void registerSelectExpression(AST selectExpression) {
+ }
+
+ protected AST handleSelectedPropertyRef(AST propertyRef) {
+ return propertyRef;
+ }
+
+}
+
+// Statement rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * The main grammar rule
+ */
+statement :
+ updateStatement
+ | deleteStatement
+ | insertStatement
+ | selectStatement
+;
+
+
+// <tt>UPDATE</tt> statement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an <tt>UPDATE</tt> statement
+ */
+updateStatement :
+ #(
+ UPDATE { pushStatement( #updateStatement ); }
+ (VERSIONED)?
+ ENTITY_NAME (ALIAS)?
+ setClause
+ (whereClause)? { popStatement(); }
+ )
+;
+
+setClause :
+ #( SET (assignment)+ )
+;
+
+assignment :
+ #( ASSIGNMENT_OP assignmentField newValue )
+;
+
+assignmentField :
+ propertyReference
+;
+
+newValue :
+ valueExpression
+;
+
+
+
+// <tt>DELETE</tt> statement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>DELETE</tt> statement
+ */
+deleteStatement :
+ #(
+ DELETE { pushStatement( #deleteStatement ); }
+ ENTITY_NAME (ALIAS)?
+ (whereClause)? { popStatement(); }
+ )
+;
+
+
+// <tt>INSERT</tt> statement
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>INSERT</tt> statement
+ */
+insertStatement :
+ #(
+ INSERT { pushStatement( #insertStatement ); }
+ intoClause
+ queryExpression { popStatement(); }
+ )
+;
+
+intoClause :
+ #( INTO ENTITY_NAME insertabilitySpecification )
+;
+
+insertabilitySpecification :
+ #( INSERTABILITY_SPEC (insertablePropertySpecification)+ )
+;
+
+/**
+ * The property being inserted into.
+ */
+insertablePropertySpecification :
+ IDENT
+;
+
+
+// <tt>SELECT</tt> statement rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>SELECT</tt> statement.
+ * <p/>
+ * This corresponds most closely to the <cursor specification> rule in ISO/ANSI
SQL...
+ */
+selectStatement :
+ #( QUERY { pushStatement( #selectStatement ); } queryExpression (orderByClause)? ) {
popStatement(); }
+;
+
+orderByClause :
+ #( ORDER_BY (sortSpecification)+ )
+;
+
+sortSpecification :
+ #( SORT_SPEC sortKey (collationSpecification)? (orderingSpecification)? )
+;
+
+sortKey :
+ // todo : do we want to explicitly limit these?
+ valueExpression
+;
+
+collationSpecification :
+ COLLATE
+;
+
+orderingSpecification :
+ ORDER_SPEC
+;
+
+queryExpression :
+ querySpec ( ( UNION | INTERSECT | EXCEPT ) (ALL)? querySpec )*
+;
+
+subquery :
+ queryExpression
+;
+
+querySpec :
+ #( QUERY_SPEC selectFrom ( whereClause )? ( groupByClause ( havingClause )? )? )
+;
+
+
+selectFrom :
+ #( SELECT_FROM fromClause (selectClause)? )
+;
+
+
+// table/persister related rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+fromClause :
+ #( FROM (persisterSpace)+ )
+;
+
+persisterSpace :
+ #( PERSISTER_SPACE entityPersisterReference ( explicitJoin )* )
+;
+
+entityPersisterReference! :
+ #( epr:ENTITY_PERSISTER_REF en:ENTITY_NAME (a:ALIAS)? (pf:PROP_FETCH)? ) {
+// #entityPersisterReference = buildEntityPersisterReference( en, a, pf );
+ AST entityName = normalizeEntityName( #en );
+ AST alias = normalizeAlias( #a );
+ #entityPersisterReference = #( #epr, entityName, alias, #pf );
+ registerPersisterReference( #entityPersisterReference );
+ }
+;
+
+explicitJoin :
+ explicitPersisterJoin
+ | explicitPropertyJoin
+;
+
+explicitPersisterJoin :
+ #(
+ j:PERSISTER_JOIN (
+ CROSS entityPersisterReference
+ | qualifiedJoinType e:entityPersisterReference (on:onFragment[#e])?
+ )
+ ) {
+ #j.setType( JOIN );
+ #j.setText( "join" );
+ }
+;
+
+explicitPropertyJoin! :
+ #( j:PROPERTY_JOIN jt:qualifiedJoinType (f:FETCH)? (a:ALIAS)? (pf:PROP_FETCH)?
{pushFromClausePropertyPathContext(#jt,#f,#a,#pf);} prop:propertyReference
(with:withFragment[#prop])? {popFromClausePropertyPathContext();} )
+;
+
+qualifiedJoinType :
+ ( (LEFT | RIGHT) (OUTER)? )
+ | INNER
+;
+
+onFragment[ AST rhsPersisterReference ] :
+ #( o:ON { pushOnFragmentPropertyPathContext( rhsPersisterReference ); }
sc:searchCondition ) {
+ #onFragment = #( o, sc );
+ }
+;
+
+withFragment[ AST rhsPropertyReference ] :
+ #( w:WITH { pushWithFragmentPropertyPathContext( rhsPropertyReference ); }
sc:searchCondition ) {
+ #withFragment = #( w, sc );
+ applyWithFragment( #withFragment );
+ popWithFragmentPropertyPathContext();
+ }
+;
+
+
+// select clause related rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+selectClause :
+ #( SELECT (d:DISTINCT)? { pushSelectClausePropertyPathContext(); }
rootSelectExpression ) {
+ popSelectClausePropertyPathContext();
+ }
+;
+
+rootSelectExpression :
+ #( SELECT_LIST explicitSelectList )
+ | #( SELECT_ITEM ( rootDynamicInstantiation | jpaSelectObjectSyntax ) )
+;
+
+explicitSelectList :
+ ( explicitSelectItem )+
+;
+
+explicitSelectItem :
+ #( SELECT_ITEM selectExpression ) {
+ registerSelectItem( #explicitSelectItem );
+ }
+;
+
+selectExpression :
+ valueExpression ( ALIAS )?
+;
+
+rootDynamicInstantiation :
+ #( DYNAMIC_INSTANTIATION dynamicInstantiationArguments ) {
+ registerSelectItem( #rootDynamicInstantiation );
+ }
+;
+
+nestedDynamicInstantiation :
+ #( DYNAMIC_INSTANTIATION dynamicInstantiationArguments (ALIAS)? )
+;
+
+dynamicInstantiationArguments :
+ ( dynamicInstantiationArgument )+
+;
+
+dynamicInstantiationArgument :
+ #( DYNAMIC_INSTANTIATION_ARG ( nestedDynamicInstantiation | selectExpression ) )
+;
+
+jpaSelectObjectSyntax! :
+ #( SELECT_ITEM OBJECT a:ALIAS_REF ) {
+ if ( isPersisterReferenceAlias( #a ) ) {
+ #jpaSelectObjectSyntax = #a;
+ }
+ else {
+ throw new DetailedSemanticException( "token [" + #a.getText() +
"] in syntax [object (" + #a.getText() + ")] must refer to persister
reference", #a );
+ }
+ }
+;
+
+
+
+// where clause rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+whereClause :
+ #( WHERE searchCondition )
+;
+
+
+
+// group by clause rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+groupByClause :
+ #( GROUP_BY groupingSpecification )
+;
+
+groupingSpecification :
+ ( groupingValue )+
+;
+
+groupingValue :
+ valueExpression ( collationSpecification )?
+;
+
+
+
+// having clause related rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+havingClause :
+ #( HAVING searchCondition )
+;
+
+
+
+// value/expression recognition rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+numericValueExpression :
+ valueExpression
+;
+
+stringValueExpression :
+ characterValueExpression
+;
+
+characterValueExpression :
+ valueExpression
+;
+
+intervalValueExpression :
+ valueExpression
+;
+
+datetimeValueExpression :
+ valueExpression
+;
+
+valueExpression :
+ #( CONCATENATION_OP ARGLIST ( characterValueExpression )+ )
+ | #( UNARY_MINUS numericValueExpression )
+ | #( UNARY_PLUS numericValueExpression )
+ | #( PLUS_SIGN valueExpression valueExpression )
+ | #( MINUS_SIGN valueExpression valueExpression )
+ | #( ASTERISK numericValueExpression numericValueExpression )
+ | #( SOLIDUS numericValueExpression numericValueExpression )
+ | valueExpressionPrimary
+;
+
+valueExpressionPrimary :
+ (persisterReferenceAliasCheck) => nonCollectionPersisterAliasReference
+ | caseExpression
+// | quantifiedExpression
+ | function
+ | collectionFunction
+ | collectionExpression
+ | literal
+ | parameter
+ | propertyReference
+;
+
+
+function : {
+ startingFunction();
+ }
+ ( standardFunction | setFunction ) {
+ endingFunction();
+ }
+;
+
+nonCollectionPersisterAliasReference :
+ a:persisterAliasReference {
+ if ( isCollectionPersisterReferenceAlias( #a ) ) {
+ throw new DetailedSemanticException( "expecting non-collection alias
reference [" + #a.getText() + "]", #a );
+ }
+ }
+;
+
+persisterAliasReference :
+ ALIAS_REF
+ | a:IDENT { isPersisterReferenceAlias( #a ) }? {
+ #a.setType( ALIAS_REF );
+ }
+;
+
+caseExpression :
+ caseAbbreviation
+ | caseSpecification
+;
+
+caseAbbreviation :
+ #( NULLIF valueExpression valueExpression )
+ | #( COALESCE ( valueExpression )+ )
+;
+
+caseSpecification :
+ simpleCase
+ | searchedCase
+;
+
+simpleCase :
+ #( SIMPLE_CASE valueExpression (simpleCaseWhenClause)+ (elseClause)? END )
+;
+
+simpleCaseWhenClause :
+ #( WHEN valueExpression THEN result )
+;
+
+result :
+ valueExpression
+;
+
+elseClause :
+ #( ELSE result )
+;
+
+searchedCase :
+ #( SEARCHED_CASE (searchedWhenClause)+ (elseClause)? END )
+;
+
+searchedWhenClause :
+ #( WHEN searchCondition THEN valueExpression )
+;
+
+//quantifiedExpression :
+// // todo : this should be a function of the predicates (logicalExpression) not of
concatenation/additiveExpression
+// // they can come only in very certain circumstances.
+// #( ( SOME^ | EXISTS^ | ALL^ | ANY^ ) ( IDENT | collectionExpression | (LEFT_PAREN! (
subQuery ) RIGHT_PAREN!) ) )
+//;
+
+standardFunction :
+ castFunction
+ | concatFunction
+ | substringFunction
+ | trimFunction
+ | upperFunction
+ | lowerFunction
+ | lengthFunction
+ | locateFunction
+ | absFunction
+ | sqrtFunction
+ | modFunction
+ | sizeFunction
+ | indexFunction
+ | currentDateFunction
+ | currentTimeFunction
+ | currentTimestampFunction
+ | extractFunction
+ | positionFunction
+ | charLengthFunction
+ | octetLengthFunction
+ | bitLengthFunction
+;
+
+castFunction :
+ #( CAST valueExpression dataType )
+;
+
+dataType :
+ // todo : temp...
+ IDENT
+;
+
+concatFunction :
+ #( CONCAT (valueExpression)* )
+;
+
+substringFunction :
+ #( SUBSTRING characterValueExpression numericValueExpression
(numericValueExpression)? )
+;
+
+trimFunction :
+ #( TRIM ( LEADING | TRAILING | BOTH ) CHAR_STRING characterValueExpression )
+;
+
+upperFunction :
+ #( UPPER characterValueExpression )
+;
+
+lowerFunction :
+ #( LOWER characterValueExpression )
+;
+
+lengthFunction :
+ #( LENGTH characterValueExpression )
+;
+
+locateFunction :
+ #( LOCATE characterValueExpression characterValueExpression (numericValueExpression)?
)
+;
+
+absFunction :
+ #( ABS numericValueExpression )
+;
+
+sqrtFunction :
+ #( SQRT numericValueExpression )
+;
+
+modFunction :
+ #( MOD numericValueExpression numericValueExpression )
+;
+
+sizeFunction :
+ #( SIZE collectionPropertyReference )
+;
+
+indexFunction :
+ #( INDEX ALIAS_REF )
+;
+
+currentDateFunction :
+ CURRENT_DATE
+;
+
+currentTimeFunction :
+ CURRENT_TIME
+;
+
+currentTimestampFunction :
+ CURRENT_TIMESTAMP
+;
+
+extractFunction :
+ #( EXTRACT extractField FROM extractSource )
+;
+
+extractField :
+ datetimeField
+ | timeZoneField
+;
+
+datetimeField :
+ nonSecondDatetimeField
+ | SECOND
+;
+
+timeZoneField :
+ TIMEZONE_HOUR
+ | TIMEZONE_MINUTE
+;
+
+extractSource :
+ datetimeValueExpression
+;
+
+positionFunction :
+ #( POSITION characterValueExpression characterValueExpression )
+;
+
+charLengthFunction :
+ #( CHAR_LENGTH characterValueExpression )
+ | #( CHARACTER_LENGTH characterValueExpression )
+;
+
+octetLengthFunction :
+ #( OCTET_LENGTH characterValueExpression )
+;
+
+bitLengthFunction :
+ #( BIT_LENGTH characterValueExpression )
+;
+
+setFunction :
+ #( SUM numericValueExpression )
+ | #( AVG numericValueExpression )
+ | #( MAX numericValueExpression )
+ | #( MIN numericValueExpression )
+ | #( COUNT {startingFunction();} ( ASTERISK | ( ( DISTINCT | ALL )? (
propertyReference | literal ) ) ) {endingFunction();} )
+;
+
+collectionFunction :
+ #( MAXELEMENT collectionPropertyReference )
+ | #( MAXINDEX collectionPropertyReference )
+ | #( MINELEMENT collectionPropertyReference )
+ | #( MININDEX collectionPropertyReference )
+;
+
+collectionExpression :
+ #( ELEMENTS collectionPropertyReference )
+ #( INDICES collectionPropertyReference )
+;
+
+parameter :
+ p:PARAM { p.setText( Integer.toString( ordinalParamCount++ ) ); } // todo : move
this to parse?
+ | JPA_PARAM
+ | NAMED_PARAM
+;
+
+
+// literals
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+protected
+literal :
+ javaConstant
+ | numericLiteral
+ | characterLiteral
+ | dateLiteral
+ | timeLiteral
+ | timestampLiteral
+ | intervalLiteral
+;
+
+protected
+javaConstant :
+ JAVA_CONSTANT
+;
+
+protected
+numericLiteral :
+ UNSIGNED_INTEGER
+ | NUM_INT_LITERAL
+ | NUM_LONG_LITERAL
+ | NUM_DOUBLE_LITERAL
+ | NUM_FLOAT_LITERAL
+;
+
+protected
+characterLiteral :
+ CHAR_STRING
+ | NATIONAL_CHAR_STRING_LIT
+ | BIT_STRING_LIT
+ | HEX_STRING_LIT
+;
+
+protected
+dateLiteral :
+// #( DATE CHAR_STRING )
+ #( DATE characterValueExpression )
+;
+
+protected
+timeLiteral :
+// #( TIME CHAR_STRING )
+ #( TIME characterValueExpression )
+;
+
+protected
+timestampLiteral :
+// #( TIMESTAMP CHAR_STRING )
+ #( TIMESTAMP characterValueExpression )
+;
+
+protected
+intervalLiteral :
+ #( INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier )
+// #( INTERVAL ( PLUS_SIGN | MINUS_SIGN )? characterValueExpression intervalQualifier
) -- characterValueExpression causes non-determinism with + and -
+;
+
+protected
+intervalQualifier :
+ #( YEAR (precision)? ( TO MONTH )? )
+ | #( MONTH (precision)? )
+ | #( DAY (precision)? ( TO ( HOUR | MINUTE | ( SECOND (scale)? ) ) )? )
+ | #( HOUR (precision)? ( TO ( MINUTE | SECOND (scale)? ) )? )
+ | #( MINUTE (precision)? ( TO SECOND (scale)? )? )
+ | #( SECOND ( precision (scale)? )? )
+;
+
+precision :
+ NUM_INT_LITERAL
+;
+
+scale :
+ NUM_INT_LITERAL
+;
+
+//protected
+//intervalStartField :
+// nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+//
+//protected
+//intervalEndField :
+// nonSecondDatetimeField
+// | SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+
+protected
+nonSecondDatetimeField :
+ YEAR
+ | MONTH
+ | DAY
+ | HOUR
+ | MINUTE
+;
+
+
+
+// property-reference related rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+nonCollectionPropertyReference :
+ pr:propertyReference {
+ // todo : validate the property type
+ }
+;
+
+collectionPropertyReference :
+ pr:propertyReference {
+ // todo : validate the property type
+ }
+;
+
+/**
+ * The top level property ref recognition rule.
+ */
+propertyReference :
+ (unqualifiedPropertyReferenceCheck) => unqualifiedPropertyReference
+ | pathedPropertyReference
+ | indexOperation
+;
+
+/**
+ * A rule utilizing a validating semantic predicate to contextually
+ * ensure that we have unqualified property reference. Generally
+ * used from within syntactic predicates to disambiguate the match path
+ *
+ * see {@link #implicitJoinSource} for example
+ */
+unqualifiedPropertyReferenceCheck! :
+ prop:IDENT { isUnqualifiedPropertyReference( prop ) }?
+;
+
+/**
+ * AST construction rule for building AST relating to *known*
+ * unqualified property references. Do not call this rule unless
+ * you know for certain (ala, have verified via the unqualifiedPropertyRefCheck
+ * rule or similiar) that the next token is an IDENT representing an
+ * unqualified property reference.
+ */
+unqualifiedPropertyReference! :
+ prop:IDENT {
+ #unqualifiedPropertyReference = normalizeUnqualifiedPropertyReference( prop );
+ }
+;
+
+/**
+ * Perhaps better named as 'complex property ref' or 'pathed property
ref' i.e.
+ * Anyway, the basic idea is (DOT <source> IDENT)
+ */
+pathedPropertyReference! :
+ #( d:DOT source:pathedPropertyReferenceSource prop:IDENT) {
+ #pathedPropertyReference = normalizePropertyPathTerminus( #source, #prop );
+ }
+;
+
+/**
+ * The output of the implicitJoinSource rule is a {@link
org.hibernate.sql.ast.phase.resolve.patg.PropertyPathPart}
+ * reference which is a tokenized and encoded representation of the current path
expression
+ * resolution state.
+ */
+pathedPropertyReferenceSource :
+ (persisterReferenceAliasCheck) => a:IDENT { #pathedPropertyReferenceSource =
normalizeQualifiedRoot( #a ); }
+ | (unqualifiedPropertyReferenceCheck) => pr:IDENT { #pathedPropertyReferenceSource
= normalizeUnqualifiedRoot( #pr ); }
+ | intermediatePathedPropertyReference
+ | i:indexOperation { #pathedPropertyReferenceSource = normalizeIndexedRoot( #i ); }
+;
+
+/**
+ * A rule utilizing a validating semantic predicate to contextually
+ * ensure that we have an alias for a persister reference previously
+ * encountered and processed. Generally used from within syntactic
+ * predicates to disambiguate the path.
+ */
+persisterReferenceAliasCheck! :
+ alias:IDENT { isPersisterReferenceAlias( alias ) }?
+;
+
+/**
+ * AST construction rule for building AST relating to *known*
+ * persister reference aliases. Do not call this rule unless
+ * you know for certain (ala, have verified via the persisterReferenceAliasCheck
+ * rule or similiar) that the next token is an IDENT representing an
+ * alias for a persister reference
+ */
+persisterReferenceAlias! :
+ alias:IDENT {
+ #persisterReferenceAlias = resolveAlias( alias );
+ }
+;
+
+intermediatePathedPropertyReference! :
+ #( d:DOT source:pathedPropertyReferenceSource prop:IDENT ) {
+ #intermediatePathedPropertyReference = normalizePropertyPathIntermediary(
#source, #prop );
+ }
+;
+
+indexOperation
+ : #( i:INDEX_OP coll:collectionPropertyReference selector:indexSelector ) {
+ validateIndexOperationOperands( #coll, #selector );
+ }
+ ;
+
+indexSelector
+ : valueExpression
+// | literal
+// | parameter
+// | collectionFunctionCall : "index(alias)"
+ ;
+
+
+// Search conditions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Main logical/conditional rule defining boolean evaluated expressions
+ * <p/>
+ * This first level handles OR expressions
+ */
+searchCondition :
+ #( OR searchCondition searchCondition )
+ | #( AND searchCondition searchCondition )
+ | #( NOT searchCondition )
+ | predicate
+;
+
+predicate :
+ #( EQUALS_OP rowValueConstructor comparativePredicateValue )
+ | #( NOT_EQUALS_OP rowValueConstructor comparativePredicateValue )
+ | #( LESS_THAN_OP rowValueConstructor comparativePredicateValue )
+ | #( LESS_THAN_OR_EQUALS_OP rowValueConstructor comparativePredicateValue )
+ | #( GREATER_THAN_OP rowValueConstructor comparativePredicateValue )
+ | #( GREATER_THAN_OR_EQUALS_OP rowValueConstructor comparativePredicateValue )
+ | #( IS_NULL rowValueConstructor )
+ | #( IS_NOT_NULL rowValueConstructor )
+ | #( LIKE valueExpression valueExpression (escapeSpecification)? )
+ | #( NOT_LIKE valueExpression valueExpression (escapeSpecification)? )
+ | #( BETWEEN rowValueConstructor rowValueConstructor rowValueConstructor )
+ | #( NOT_BETWEEN rowValueConstructor rowValueConstructor rowValueConstructor )
+ | #( IN rowValueConstructor inPredicateValue )
+ | #( NOT_IN rowValueConstructor inPredicateValue )
+ | #( EXISTS (
+ queryExpression
+ | ( ELEMENTS | INDICES ) collectionPropertyReference
+ )
+ )
+;
+
+comparativePredicateValue :
+ rowValueConstructor
+ | ( ( SOME | ALL | ANY ) subquery )
+;
+
+escapeSpecification :
+ #( ESCAPE characterValueExpression )
+;
+
+inPredicateValue :
+ #(
+ IN_LIST (
+ queryExpression
+ | ( valueExpression )+
+ )
+ )
+;
+
+rowValueConstructor :
+ ( LEFT_PAREN ) => ( LEFT_PAREN rowValueConstructorList RIGHT_PAREN )
+ | rowValueConstructorElement
+;
+
+rowValueConstructorElement :
+ valueExpression
+ | NULL
+ | DEFAULT
+;
+
+rowValueConstructorList :
+ rowValueConstructorElement ( COMMA! rowValueConstructorElement )*
+;
+
Modified: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g 2009-01-06 17:14:14 UTC (rev
15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g 2009-01-06 20:11:13 UTC (rev
15747)
@@ -28,7 +28,7 @@
* with or without modification, you must preserve this copyright notice in its
* entirety.
*/
-package org.hibernate.hql.ast.phase.parse;
+package org.hibernate.sql.ast.phase.hql.parse;
import antlr.collections.AST;
@@ -60,10 +60,12 @@
ALIAS_REF;
ARG_LIST;
ASSIGNMENT_OP;
- CLASS_NAME;
- CONSTRUCTOR;
+ COLLECTION_PERSISTER_REF;
COLLECTION_ROLE;
+ DYNAMIC_INSTANTIATION;
+ DYNAMIC_INSTANTIATION_ARG;
ENTITY_NAME;
+ ENTITY_PERSISTER_REF;
FILTER_ENTITY;
GENERIC_FUNCTION;
INDEX_OP;
@@ -78,26 +80,31 @@
NOT_IN;
NOT_LIKE;
ORDER_SPEC;
+ PERSISTER_SPACE;
PROP_FETCH;
QUERY;
+ QUERY_SPEC;
REGISTERED_FUNCTION;
+ SEARCHED_CASE;
SELECT_FROM;
+ SELECT_ITEM;
+ SELECT_LIST;
+ SIMPLE_CASE;
SORT_KEY;
SORT_SPEC;
SQL_TOKEN;
UNARY_MINUS;
UNARY_PLUS;
- PERSISTER_SPACE;
-// WEIRD_IDENT;
-// AGGREGATE;
EXPR_LIST;
-// ROW_STAR;
VECTOR_EXPR;
+
+ PERSISTER_JOIN;
+ PROPERTY_JOIN;
}
{
- private static Logger log = LoggerFactory.getLogger( GeneratedHqlParser99.class );
+ private static Logger log = LoggerFactory.getLogger( GeneratedHqlParser.class );
protected String extractText(AST node) {
return node.getText();
@@ -107,6 +114,10 @@
return extractText( node );
}
+ protected String normalizeDynamicInstantiationClassName(AST node) {
+ return extractPath( node );
+ }
+
protected boolean isJavaConstant(String test) {
return false;
}
@@ -208,16 +219,7 @@
}
;
-protected
-className :
- p:path {
- String name = extractPath( #p );
- #className = #( [CLASS_NAME,name] );
- transferTrackingInfo( #p, #className );
- }
-;
-
// alias/correlation recognition rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
@@ -361,7 +363,7 @@
;
orderByClause :
- ORDER^ BY! sortSpecification ( COMMA! sortSpecification )*
+ ORDER_BY^ sortSpecification ( COMMA! sortSpecification )*
;
/**
@@ -415,9 +417,9 @@
;
querySpec :
- selectFrom
- ( whereClause )?
- ( groupByClause ( havingClause )? )?
+ selectFrom ( whereClause )? ( groupByClause ( havingClause )? )? {
+ #querySpec = #( [QUERY_SPEC], #querySpec );
+ }
;
selectFrom! :
@@ -476,43 +478,49 @@
CLASS! {unequivocalKeywordAsIdentifier();} en:entityName! {
log.warn( "encountered deprecated, legacy from-clause syntax :
[<alias> in class <entity-name>]" );
#a.setType( ALIAS );
- #hibernateLegacySyntax = #( #en, #a );
+ #hibernateLegacySyntax = #( [ENTITY_PERSISTER_REF], #en, #a );
}
| ( ELEMENTS! | INDICES! )? LEFT_PAREN! {unequivocalKeywordAsIdentifier();}
p:path! RIGHT_PAREN! {
log.warn( "encountered deprecated, legacy from-clause syntax :
[<alias> in <elements|indices> (<collection-ref>)]" );
// todo : properly treat ELEMENTS | INDICES...
#a.setType( ALIAS );
- #hibernateLegacySyntax = #( [JOIN,"join"], [INNER,
"inner"], #p, #a );
+ #hibernateLegacySyntax = #( [PROPERTY_JOIN,"property-join"],
[INNER, "inner"], #a, #p );
}
)
;
-mainEntityPersisterReference :
- entityName (alias)? (propertyFetch)?
+mainEntityPersisterReference! :
+ en:entityName (a:alias)? (pf:propertyFetch)? {
+ #mainEntityPersisterReference = #( [ENTITY_PERSISTER_REF], #en, #a, #pf );
+ }
;
jpaCollectionReference :
- IN! LEFT_PAREN! {unequivocalKeywordAsIdentifier();} p2:path RIGHT_PAREN! ( a2:alias
)? {
- #jpaCollectionReference = #( [JOIN,"join"], [INNER, "inner"],
#p2, #a2 );
+ IN! LEFT_PAREN! {unequivocalKeywordAsIdentifier();} p:path RIGHT_PAREN! ( a:alias )?
{
+ #jpaCollectionReference = #( [PROPERTY_JOIN,"property-join"], [INNER,
"inner"], #a, #p );
}
;
crossJoin :
- CROSS JOIN^ {prepareForCrossJoinElements();} entityName (alias)? (propertyFetch)?
+ CROSS j:JOIN^ {prepareForCrossJoinElements();} mainEntityPersisterReference {
+ j.setType( PERSISTER_JOIN );
+ j.setText( "persister-join" );
+ }
;
qualifiedJoin! :
(jt:nonCrossJoinType)? j:JOIN {if (#jt==null) #jt=#([INNER]);} (f:FETCH)?
{prepareForQualifiedJoinElements();} p:path (a:alias)? (
- // try to use the ON keyword to disambiguate
+ // use the ON keyword to disambiguate
js:joinSpecification {
if ( #f != null ) {
throw new org.hibernate.QueryException( "Cannot use fetch keyword in
conjunction with an ad hoc join" );
}
String entityName = extractPath( #p );
- #qualifiedJoin = #( #j, #jt, [ENTITY_NAME,entityName], #a, #js );
+ AST persisterReference = #( [ENTITY_PERSISTER_REF], [ENTITY_NAME,entityName],
#a );
+ #qualifiedJoin = #( [PERSISTER_JOIN,"persister-join"], #jt,
persisterReference, #js );
}
| (pf:propertyFetch)? (w:withClause)? {
- #qualifiedJoin = #( #j, #jt, #f, #a, #pf, #p, #w );
+ #qualifiedJoin = #( [PROPERTY_JOIN,"property-join"], #jt, #f, #a,
#pf, #p, #w );
}
)
;
@@ -525,6 +533,7 @@
outerJoinType :
LEFT
| RIGHT
+ | FULL // ugh!
;
joinSpecification :
@@ -545,30 +554,67 @@
// select clause related rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-selectClause
- : SELECT^ // NOTE: The '^' after a token causes the corresponding AST node to be
the root of the sub-tree.
- { weakKeywords(); } // Weak keywords can appear immediately after a SELECT token.
- (DISTINCT)? ( selectedPropertiesList | newExpression | selectObject )
- ;
+selectClause :
+ SELECT^ (DISTINCT)? { weakKeywords(); } rootSelectExpression
+;
-newExpression
- : (NEW! path) op:LEFT_PAREN^ {#op.setType(CONSTRUCTOR);} selectedPropertiesList
RIGHT_PAREN!
- ;
+rootSelectExpression :
+ explicitSelectList
+ | rootDynamicInstantiation
+ | jpaSelectObjectSyntax
+;
-selectObject
- : OBJECT^ LEFT_PAREN! identifier RIGHT_PAREN!
- ;
+explicitSelectList :
+ explicitSelectItem ( COMMA! explicitSelectItem )* {
+ #explicitSelectList = #( [SELECT_LIST], #explicitSelectList );
+ }
+;
-selectedPropertiesList
- : aliasedExpression ( COMMA! aliasedExpression )*
- ;
+explicitSelectItem :
+ selectExpression {
+ #explicitSelectItem = #( [SELECT_ITEM], #explicitSelectItem );
+ }
+;
-aliasedExpression
- : expression ( AS^ identifier )?
- ;
+selectExpression :
+ expression ( AS! i:identifier {#i.setType(ALIAS);} )?
+;
+rootDynamicInstantiation! :
+ n:NEW! p:path op:LEFT_PAREN! args:dynamicInstantiationArgs RIGHT_PAREN! {
+ #rootDynamicInstantiation = #( [ DYNAMIC_INSTANTIATION,
normalizeDynamicInstantiationClassName( #p ) ], #args );
+ transferTrackingInfo( #n, #rootDynamicInstantiation );
+ #rootDynamicInstantiation = #( [SELECT_ITEM], #rootDynamicInstantiation );
+ transferTrackingInfo( #n, #rootDynamicInstantiation );
+ }
+;
+nestedDynamicInstantiation :
+ n:NEW! p:path op:LEFT_PAREN! args:dynamicInstantiationArgs RIGHT_PAREN! ( AS!
a:identifier {#a.setType(ALIAS);} )? {
+ #nestedDynamicInstantiation = #( [ DYNAMIC_INSTANTIATION,
normalizeDynamicInstantiationClassName( #p ) ], #args, #a );
+ transferTrackingInfo( #n, #nestedDynamicInstantiation );
+ }
+;
+dynamicInstantiationArgs :
+ dynamicInstantiationArg ( COMMA! dynamicInstantiationArg )*
+;
+
+dynamicInstantiationArg :
+ ( selectExpression | nestedDynamicInstantiation ) {
+ #dynamicInstantiationArg = #( [DYNAMIC_INSTANTIATION_ARG],
#dynamicInstantiationArg );
+ }
+;
+
+jpaSelectObjectSyntax :
+ OBJECT^ LEFT_PAREN! i:identifier RIGHT_PAREN! {
+ #i.setType(ALIAS_REF);
+ #jpaSelectObjectSyntax = #( [SELECT_ITEM], #jpaSelectObjectSyntax );
+ }
+;
+
+
+
// where clause rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
whereClause :
@@ -580,7 +626,7 @@
// group by clause rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
groupByClause :
- GROUP^ BY! groupingSpecification
+ GROUP_BY^ groupingSpecification
;
groupingSpecification :
@@ -758,8 +804,8 @@
;
caseAbbreviation :
- ( NULLIF LEFT_PAREN unaryExpression COMMA unaryExpression RIGHT_PAREN )
- | ( COALESCE LEFT_PAREN unaryExpression (COMMA unaryExpression)* RIGHT_PAREN )
+ ( NULLIF^ LEFT_PAREN! unaryExpression COMMA! unaryExpression RIGHT_PAREN! )
+ | ( COALESCE^ LEFT_PAREN! unaryExpression (COMMA! unaryExpression)* RIGHT_PAREN! )
;
caseSpecification :
@@ -768,7 +814,9 @@
;
simpleCase :
- CASE unaryExpression (simpleCaseWhenClause)+ (elseClause)? END
+ c:CASE^ unaryExpression (simpleCaseWhenClause)+ (elseClause)? END {
+ #c.setType( SIMPLE_CASE );
+ }
;
simpleCaseWhenClause :
@@ -784,7 +832,9 @@
;
searchedCase :
- CASE (searchedWhenClause)+ (elseClause)? END
+ c:CASE^ (searchedWhenClause)+ (elseClause)? END {
+ c.setType( SEARCHED_CASE );
+ }
;
searchedWhenClause :
@@ -906,19 +956,19 @@
;
currentDateFunction :
- CURRENT_DATE ( LEFT_PAREN! RIGHT_PAREN! )?
+ CURRENT_DATE^ ( LEFT_PAREN! RIGHT_PAREN! )?
;
currentTimeFunction :
- CURRENT_TIME ( LEFT_PAREN! RIGHT_PAREN! )?
+ CURRENT_TIME^ ( LEFT_PAREN! RIGHT_PAREN! )?
;
currentTimestampFunction :
- CURRENT_TIMESTAMP ( LEFT_PAREN! RIGHT_PAREN! )?
+ CURRENT_TIMESTAMP^ ( LEFT_PAREN! RIGHT_PAREN! )?
;
extractFunction :
- EXTRACT^ LEFT_PAREN! extractField FROM extractSource RIGHT_PAREN!
+ EXTRACT^ LEFT_PAREN! extractField FROM! extractSource RIGHT_PAREN!
;
extractField :
@@ -1075,64 +1125,64 @@
| FALSE
;
-literal :
- numericLiteral
- | characterLiteral
- | dateLiteral
- | timeLiteral
- | timestampLiteral
- | intervalLiteral
-;
-
-numericLiteral :
- UNSIGNED_INTEGER
- | NUM_INT_LITERAL
- | NUM_LONG_LITERAL
- | NUM_DOUBLE_LITERAL
- | NUM_FLOAT_LITERAL
-;
-
-characterLiteral :
- CHAR_STRING
- | NATIONAL_CHAR_STRING_LIT
- | BIT_STRING_LIT
- | HEX_STRING_LIT
-;
-
-dateLiteral :
- DATE^ CHAR_STRING
-;
-
-timeLiteral :
- TIME^ CHAR_STRING
-;
-
-timestampLiteral :
- TIMESTAMP^ CHAR_STRING
-;
-
-intervalLiteral :
- INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier
-;
-
-intervalQualifier :
- intervalStartField ( TO intervalEndField | )
- | SECOND ( LEFT_PAREN UNSIGNED_INTEGER ( COMMA UNSIGNED_INTEGER )? RIGHT_PAREN )?
-;
-
-intervalStartField :
- nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
-;
-
-intervalEndField :
- nonSecondDatetimeField
- | SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
-;
-
-nonSecondDatetimeField :
- YEAR
- | MONTH
- | DAY
- | HOUR
- | MINUTE
-;
+//literal :
+// numericLiteral
+// | characterLiteral
+// | dateLiteral
+// | timeLiteral
+// | timestampLiteral
+// | intervalLiteral
+//;
+//
+//numericLiteral :
+// UNSIGNED_INTEGER
+// | NUM_INT_LITERAL
+// | NUM_LONG_LITERAL
+// | NUM_DOUBLE_LITERAL
+// | NUM_FLOAT_LITERAL
+//;
+//
+//characterLiteral :
+// CHAR_STRING
+// | NATIONAL_CHAR_STRING_LIT
+// | BIT_STRING_LIT
+// | HEX_STRING_LIT
+//;
+//
+//dateLiteral :
+// DATE^ CHAR_STRING
+//;
+//
+//timeLiteral :
+// TIME^ CHAR_STRING
+//;
+//
+//timestampLiteral :
+// TIMESTAMP^ CHAR_STRING
+//;
+//
+//intervalLiteral :
+// INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier
+//;
+//
+//intervalQualifier :
+// intervalStartField ( TO intervalEndField | )
+// | SECOND ( LEFT_PAREN UNSIGNED_INTEGER ( COMMA UNSIGNED_INTEGER )? RIGHT_PAREN )?
+//;
+//
+//intervalStartField :
+// nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+//
+//intervalEndField :
+// nonSecondDatetimeField
+// | SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+//;
+//
+//nonSecondDatetimeField :
+// YEAR
+// | MONTH
+// | DAY
+// | HOUR
+// | MINUTE
+//;
Copied: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g (from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g
(rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/parse.g 2009-01-06 20:11:13 UTC
(rev 15747)
@@ -0,0 +1,429 @@
+header
+{
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+}
+/**
+ * Antlr grammar for dealing with <tt>order-by</tt> mapping fragments.
+ *
+ * @author Steve Ebersole
+ */
+class GeneratedOrderByFragmentParser extends Parser;
+
+options
+{
+ exportVocab=OrderByTemplate;
+ buildAST=true;
+ k=3;
+}
+
+tokens
+{
+ // synthetic tokens
+ ORDER_BY;
+ SORT_SPEC;
+ ORDER_SPEC;
+ SORT_KEY;
+ EXPR_LIST;
+ DOT;
+ IDENT_LIST;
+ COLUMN_REF;
+
+ COLLATE="collate";
+ ASCENDING="asc";
+ DESCENDING="desc";
+}
+
+
+{
+ /**
+ * Extract a node's text.
+ *
+ * @param ast The node
+ *
+ * @return The text.
+ */
+ protected final String extractText(AST ast) {
+ // for some reason, within AST creation blocks "[]" I am somtimes
unable to refer to the AST.getText() method
+ // using #var (the #var is not interpreted as the rule's output AST).
+ return ast.getText();
+ }
+
+ /**
+ * Process the given node as a quote identifier. These need to be quoted in the
dialect-specific way.
+ *
+ * @param ident The quoted-identifier node.
+ *
+ * @return The processed node.
+ *
+ * @see org.hibernate.dialect.Dialect#quote
+ */
+ protected AST quotedIdentifier(AST ident) {
+ return ident;
+ }
+
+ /**
+ * Process the given node as a quote string.
+ *
+ * @param ident The quoted string. This is used from within function param
recognition, and represents a
+ * SQL-quoted string.
+ *
+ * @return The processed node.
+ */
+ protected AST quotedString(AST ident) {
+ return ident;
+ }
+
+ /**
+ * A check to see if the text of the given node represents a known function name.
+ *
+ * @param ast The node whose text we want to check.
+ *
+ * @return True if the node's text is a known function name, false otherwise.
+ *
+ * @see org.hibernate.dialect.function.SQLFunctionRegistry
+ */
+ protected boolean isFunctionName(AST ast) {
+ return false;
+ }
+
+ /**
+ * Process the given node as a function.
+ *
+ * @param The node representing the function invocation (including parameters as
subtree components).
+ *
+ * @return The processed node.
+ */
+ protected AST resolveFunction(AST ast) {
+ return ast;
+ }
+
+ /**
+ * Process the given node as an IDENT. May represent either a column reference or a
property reference.
+ *
+ * @param ident The node whose text represents either a column or property
reference.
+ *
+ * @return The processed node.
+ */
+ protected AST resolveIdent(AST ident) {
+ return ident;
+ }
+
+ /**
+ * Allow post processing of each <tt>sort specification</tt>
+ *
+ * @param The grammar-built sort specification subtree.
+ *
+ * @return The processed sort specification subtree.
+ */
+ protected AST postProcessSortSpecification(AST sortSpec) {
+ return sortSpec;
+ }
+
+}
+
+/**
+ * Main recognition rule for this grammar
+ */
+orderByFragment :
+ sortSpecification ( COMMA! sortSpecification )* {
+ #orderByFragment = #( [ORDER_BY, "order-by"], #orderByFragment );
+ }
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>sort specification</tt>,
which is essentially each thing upon which
+ * the results should be sorted.
+ */
+sortSpecification :
+ sortKey (collationSpecification)? (orderingSpecification)? {
+ #sortSpecification = #( [SORT_SPEC, "{sort specification}"],
#sortSpecification );
+ #sortSpecification = postProcessSortSpecification( #sortSpecification );
+ }
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>sort key</tt> which is the
expression (column, function, etc) upon
+ * which to base the sorting.
+ */
+sortKey! :
+ e:expression {
+ #sortKey = #( [SORT_KEY, "sort key"], #e );
+ }
+;
+
+/**
+ * Reconition rule what this grammar recognizes as valid <tt>sort key</tt>.
+ */
+expression! :
+ HARD_QUOTE qi:IDENT HARD_QUOTE {
+ #expression = quotedIdentifier( #qi );
+ }
+ | ( IDENT (DOT IDENT)* OPEN_PAREN ) => f:functionCall {
+ #expression = #f;
+ }
+ | p:simplePropertyPath {
+ #expression = resolveIdent( #p );
+ }
+ | i:IDENT {
+ if ( isFunctionName( #i ) ) {
+ #expression = resolveFunction( #i );
+ }
+ else {
+ #expression = resolveIdent( #i );
+ }
+ }
+;
+
+/**
+ * Intended for use as a syntactic predicate to determine whether an IDENT represents a
known SQL function name.
+ */
+functionCallCheck! :
+ IDENT (DOT IDENT)* OPEN_PAREN { true }?
+;
+
+/**
+ * Recognition rule for a function call
+ */
+functionCall! :
+ fn:functionName OPEN_PAREN pl:functionParameterList CLOSE_PAREN {
+ #functionCall = #( [IDENT, extractText( #fn )], #pl );
+ #functionCall = resolveFunction( #functionCall );
+ }
+;
+
+/**
+ * A function-name is an IDENT followed by zero or more (DOT IDENT) sequences
+ */
+functionName {
+ StringBuffer buffer = new StringBuffer();
+ }
+ : i:IDENT { buffer.append( i.getText() ); }
+ ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )* {
+ #functionName = #( [IDENT,buffer.toString()] );
+ }
+ ;
+
+/**
+ * Recognition rule used to "wrap" all function parameters into an EXPR_LIST
node
+ */
+functionParameterList :
+ functionParameter ( COMMA! functionParameter )* {
+ #functionParameterList = #( [EXPR_LIST, "{param list}"],
#functionParameterList );
+ }
+;
+
+/**
+ * Recognized function parameters.
+ */
+functionParameter :
+ expression
+ | NUM_DOUBLE
+ | NUM_FLOAT
+ | NUM_INT
+ | NUM_LONG
+ | QUOTED_STRING {
+ #functionParameter = quotedString( #functionParameter );
+ }
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>collation
specification</tt> used to allow specifying that sorting for
+ * the given {@link #sortSpecification} be treated within a specific character-set.
+ */
+collationSpecification! :
+ c:COLLATE cn:collationName {
+ #collationSpecification = #( [COLLATE, extractText( #cn )] );
+ }
+;
+
+/**
+ * The collation name wrt {@link #collationSpecification}. Namely, the character-set.
+ */
+collationName :
+ IDENT
+;
+
+/**
+ * Reconition rule for what ANSI SQL terms the <tt>ordering
specification</tt>; <tt>ASCENDING</tt> or
+ * <tt>DESCENDING</tt>.
+ */
+orderingSpecification! :
+ ( "asc" | "ascending" ) {
+ #orderingSpecification = #( [ORDER_SPEC, "asc"] );
+ }
+ | ( "desc" | "descending") {
+ #orderingSpecification = #( [ORDER_SPEC, "desc"] );
+ }
+;
+
+/**
+ * A simple-property-path is an IDENT followed by one or more (DOT IDENT) sequences
+ */
+simplePropertyPath {
+ StringBuffer buffer = new StringBuffer();
+ }
+ : i:IDENT { buffer.append( i.getText() ); }
+ ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )+ {
+ #simplePropertyPath = #( [IDENT,buffer.toString()] );
+ }
+;
+
+
+// **** LEXER ******************************************************************
+
+/**
+ * Lexer for the <tt>order-by</tt> fragment parser
+
+ * @author Steve Ebersole
+ * @author Joshua Davis
+ */
+class GeneratedOrderByLexer extends Lexer;
+
+options {
+ exportVocab=OrderByTemplate;
+ testLiterals = false;
+ k=2;
+ charVocabulary='\u0000'..'\uFFFE'; // Allow any char but \uFFFF (16 bit
-1, ANTLR's EOF character)
+ caseSensitive = false;
+ caseSensitiveLiterals = false;
+}
+
+// -- Keywords --
+
+OPEN_PAREN: '(';
+CLOSE_PAREN: ')';
+
+COMMA: ',';
+
+HARD_QUOTE: '`';
+
+IDENT options { testLiterals=true; }
+ : ID_START_LETTER ( ID_LETTER )*
+ ;
+
+protected
+ID_START_LETTER
+ : '_'
+ | '$'
+ | 'a'..'z'
+ | '\u0080'..'\ufffe' // HHH-558 : Allow unicode chars in
identifiers
+ ;
+
+protected
+ID_LETTER
+ : ID_START_LETTER
+ | '0'..'9'
+ ;
+
+QUOTED_STRING
+ : '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
+ ;
+
+protected
+ESCqs
+ :
+ '\'' '\''
+ ;
+
+//--- From the Java example grammar ---
+// a numeric literal
+NUM_INT
+ {boolean isDecimal=false; Token t=null;}
+ : '.' {_ttype = DOT;}
+ ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
+ {
+ if (t != null && t.getText().toUpperCase().indexOf('F')>=0)
+ {
+ _ttype = NUM_FLOAT;
+ }
+ else
+ {
+ _ttype = NUM_DOUBLE; // assume double
+ }
+ }
+ )?
+ | ( '0' {isDecimal = true;} // special case for just '0'
+ ( ('x')
+ ( // hex
+ // the 'e'|'E' and float suffix stuff look
+ // like hex digits, hence the (...)+ doesn't
+ // know when to stop: ambig. ANTLR resolves
+ // it correctly by matching immediately. It
+ // is therefore ok to hush warning.
+ options { warnWhenFollowAmbig=false; }
+ : HEX_DIGIT
+ )+
+ | ('0'..'7')+ // octal
+ )?
+ | ('1'..'9') ('0'..'9')* {isDecimal=true;} //
non-zero decimal
+ )
+ ( ('l') { _ttype = NUM_LONG; }
+
+ // only check to see if it's a float if looks like decimal so far
+ | {isDecimal}?
+ ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
+ | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
+ | f4:FLOAT_SUFFIX {t=f4;}
+ )
+ {
+ if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0)
+ {
+ _ttype = NUM_FLOAT;
+ }
+ else
+ {
+ _ttype = NUM_DOUBLE; // assume double
+ }
+ }
+ )?
+ ;
+
+// hexadecimal digit (again, note it's protected!)
+protected
+HEX_DIGIT
+ : ('0'..'9'|'a'..'f')
+ ;
+
+// a couple protected methods to assist in matching floating point numbers
+protected
+EXPONENT
+ : ('e') ('+'|'-')? ('0'..'9')+
+ ;
+
+protected
+FLOAT_SUFFIX
+ : 'f'|'d'
+ ;
+
+WS : ( ' '
+ | '\t'
+ | '\r' '\n' { newline(); }
+ | '\n' { newline(); }
+ | '\r' { newline(); }
+ )
+ {$setType(Token.SKIP);} //ignore this token
+ ;
Copied: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g (from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g)
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g
(rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order/render.g 2009-01-06 20:11:13 UTC
(rev 15747)
@@ -0,0 +1,88 @@
+header
+{
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+}
+/**
+ * Antlr grammar for rendering <tt>ORDER_BY</tt> trees as described by the
{@link OrderByFragmentParser}
+ *
+ * @author Steve Ebersole
+ */
+class GeneratedOrderByFragmentRenderer extends TreeParser;
+
+options {
+ importVocab=OrderByTemplate;
+ buildAST=false;
+}
+
+{
+ // the buffer to which we write the resulting SQL.
+ private StringBuffer buffer = new StringBuffer();
+
+ protected void out(String text) {
+ buffer.append( text );
+ }
+
+ protected void out(AST ast) {
+ buffer.append( ast.getText() );
+ }
+
+ /*package*/ String getRenderedFragment() {
+ return buffer.toString();
+ }
+}
+
+orderByFragment :
+ #( ORDER_BY sortSpecification ( {out(", ");} sortSpecification)* )
+;
+
+sortSpecification :
+ #( SORT_SPEC sortKeySpecification (collationSpecification)? (orderingSpecification)?
)
+;
+
+sortKeySpecification :
+ #( SORT_KEY sortKey )
+;
+
+sortKey :
+ i:IDENT {
+ out( #i );
+ }
+;
+
+collationSpecification :
+ c:COLLATE {
+ out( " collate " );
+ out( c );
+ }
+;
+
+orderingSpecification :
+ o:ORDER_SPEC {
+ out( " " );
+ out( #o );
+ }
+;
\ No newline at end of file
Deleted: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g 2009-01-06 17:14:14
UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by-render.g 2009-01-06 20:11:13
UTC (rev 15747)
@@ -1,92 +0,0 @@
-header
-{
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.sql.ordering.antlr;
-}
-/**
- * Antlr grammar for rendering <tt>ORDER_BY</tt> trees as described by the
{@link OrderByFragmentParser}
-
- * @author Steve Ebersole
- */
-class GeneratedOrderByFragmentRenderer extends TreeParser;
-
-options {
- importVocab=OrderByTemplate;
- buildAST=false;
-}
-
-{
- // the buffer to which we write the resulting SQL.
- private StringBuffer buffer = new StringBuffer();
-
- protected void out(String text) {
- buffer.append( text );
- }
-
- protected void out(AST ast) {
- buffer.append( ast.getText() );
- }
-
- /*package*/ String getRenderedFragment() {
- return buffer.toString();
- }
-}
-
-orderByFragment
- : #(
- ORDER_BY sortSpecification ( {out(", ");} sortSpecification)*
- )
- ;
-
-sortSpecification
- : #(
- SORT_SPEC sortKeySpecification (collationSpecification)?
(orderingSpecification)?
- )
- ;
-
-sortKeySpecification
- : #(SORT_KEY sortKey)
- ;
-
-sortKey
- : i:IDENT {
- out( #i );
- }
- ;
-
-collationSpecification
- : c:COLLATE {
- out( " collate " );
- out( c );
- }
- ;
-
-orderingSpecification
- : o:ORDER_SPEC {
- out( " " );
- out( #o );
- }
- ;
\ No newline at end of file
Deleted: core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g 2009-01-06 17:14:14 UTC (rev
15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/order-by.g 2009-01-06 20:11:13 UTC (rev
15747)
@@ -1,440 +0,0 @@
-header
-{
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- *
- */
-package org.hibernate.sql.ordering.antlr;
-}
-/**
- * Antlr grammar for dealing with <tt>order-by</tt> mapping fragments.
-
- * @author Steve Ebersole
- */
-class GeneratedOrderByFragmentParser extends Parser;
-
-options
-{
- exportVocab=OrderByTemplate;
- buildAST=true;
- k=3;
-}
-
-tokens
-{
- // synthetic tokens
- ORDER_BY;
- SORT_SPEC;
- ORDER_SPEC;
- SORT_KEY;
- EXPR_LIST;
- DOT;
- IDENT_LIST;
- COLUMN_REF;
-
- COLLATE="collate";
- ASCENDING="asc";
- DESCENDING="desc";
-}
-
-
-{
- /**
- * Method for logging execution trace information.
- *
- * @param msg The trace message.
- */
- protected void trace(String msg) {
- System.out.println( msg );
- }
-
- /**
- * Extract a node's text.
- *
- * @param ast The node
- *
- * @return The text.
- */
- protected final String extractText(AST ast) {
- // for some reason, within AST creation blocks "[]" I am somtimes
unable to refer to the AST.getText() method
- // using #var (the #var is not interpreted as the rule's output AST).
- return ast.getText();
- }
-
- /**
- * Process the given node as a quote identifier. These need to be quoted in the
dialect-specific way.
- *
- * @param ident The quoted-identifier node.
- *
- * @return The processed node.
- *
- * @see org.hibernate.dialect.Dialect#quote
- */
- protected AST quotedIdentifier(AST ident) {
- return ident;
- }
-
- /**
- * Process the given node as a quote string.
- *
- * @param ident The quoted string. This is used from within function param
recognition, and represents a
- * SQL-quoted string.
- *
- * @return The processed node.
- */
- protected AST quotedString(AST ident) {
- return ident;
- }
-
- /**
- * A check to see if the text of the given node represents a known function name.
- *
- * @param ast The node whose text we want to check.
- *
- * @return True if the node's text is a known function name, false otherwise.
- *
- * @see org.hibernate.dialect.function.SQLFunctionRegistry
- */
- protected boolean isFunctionName(AST ast) {
- return false;
- }
-
- /**
- * Process the given node as a function.
- *
- * @param The node representing the function invocation (including parameters as
subtree components).
- *
- * @return The processed node.
- */
- protected AST resolveFunction(AST ast) {
- return ast;
- }
-
- /**
- * Process the given node as an IDENT. May represent either a column reference or a
property reference.
- *
- * @param ident The node whose text represents either a column or property
reference.
- *
- * @return The processed node.
- */
- protected AST resolveIdent(AST ident) {
- return ident;
- }
-
- /**
- * Allow post processing of each <tt>sort specification</tt>
- *
- * @param The grammar-built sort specification subtree.
- *
- * @return The processed sort specification subtree.
- */
- protected AST postProcessSortSpecification(AST sortSpec) {
- return sortSpec;
- }
-
-}
-
-/**
- * Main recognition rule for this grammar
- */
-orderByFragment { trace("orderByFragment"); }
- : sortSpecification ( COMMA! sortSpecification )* {
- #orderByFragment = #( [ORDER_BY, "order-by"], #orderByFragment );
- }
- ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>sort specification</tt>,
which is essentially each thing upon which
- * the results should be sorted.
- */
-sortSpecification { trace("sortSpecification"); }
- : sortKey (collationSpecification)? (orderingSpecification)? {
- #sortSpecification = #( [SORT_SPEC, "{sort specification}"],
#sortSpecification );
- #sortSpecification = postProcessSortSpecification( #sortSpecification );
- }
- ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>sort key</tt> which is the
expression (column, function, etc) upon
- * which to base the sorting.
- */
-sortKey! { trace("sortKey"); }
- : e:expression {
- #sortKey = #( [SORT_KEY, "sort key"], #e );
- }
- ;
-
-/**
- * Reconition rule what this grammar recognizes as valid <tt>sort key</tt>.
- */
-expression! { trace("expression"); }
- : HARD_QUOTE qi:IDENT HARD_QUOTE {
- #expression = quotedIdentifier( #qi );
- }
- | ( IDENT (DOT IDENT)* OPEN_PAREN ) => f:functionCall {
- #expression = #f;
- }
- | p:simplePropertyPath {
- #expression = resolveIdent( #p );
- }
- | i:IDENT {
- if ( isFunctionName( #i ) ) {
- #expression = resolveFunction( #i );
- }
- else {
- #expression = resolveIdent( #i );
- }
- }
- ;
-
-/**
- * Intended for use as a syntactic predicate to determine whether an IDENT represents a
known SQL function name.
- */
-functionCallCheck! { trace("functionCallCheck"); }
- : IDENT (DOT IDENT)* OPEN_PAREN { true }?
- ;
-
-/**
- * Recognition rule for a function call
- */
-functionCall! { trace("functionCall"); }
- : fn:functionName OPEN_PAREN pl:functionParameterList CLOSE_PAREN {
- #functionCall = #( [IDENT, extractText( #fn )], #pl );
- #functionCall = resolveFunction( #functionCall );
- }
- ;
-
-/**
- * A function-name is an IDENT followed by zero or more (DOT IDENT) sequences
- */
-functionName {
- trace("functionName");
- StringBuffer buffer = new StringBuffer();
- }
- : i:IDENT { buffer.append( i.getText() ); }
- ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )* {
- #functionName = #( [IDENT,buffer.toString()] );
- }
- ;
-
-/**
- * Recognition rule used to "wrap" all function parameters into an EXPR_LIST
node
- */
-functionParameterList { trace("functionParameterList"); }
- : functionParameter ( COMMA! functionParameter )* {
- #functionParameterList = #( [EXPR_LIST, "{param list}"],
#functionParameterList );
- }
- ;
-
-/**
- * Recognized function parameters.
- */
-functionParameter { trace("functionParameter"); }
- : expression
- | NUM_DOUBLE
- | NUM_FLOAT
- | NUM_INT
- | NUM_LONG
- | QUOTED_STRING {
- #functionParameter = quotedString( #functionParameter );
- }
- ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>collation
specification</tt> used to allow specifying that sorting for
- * the given {@link #sortSpecification} be treated within a specific character-set.
- */
-collationSpecification! { trace("collationSpecification"); }
- : c:COLLATE cn:collationName {
- #collationSpecification = #( [COLLATE, extractText( #cn )] );
- }
- ;
-
-/**
- * The collation name wrt {@link #collationSpecification}. Namely, the character-set.
- */
-collationName { trace("collationSpecification"); }
- : IDENT
- ;
-
-/**
- * Reconition rule for what ANSI SQL terms the <tt>ordering
specification</tt>; <tt>ASCENDING</tt> or
- * <tt>DESCENDING</tt>.
- */
-orderingSpecification! { trace("orderingSpecification"); }
- : ( "asc" | "ascending" ) {
- #orderingSpecification = #( [ORDER_SPEC, "asc"] );
- }
- | ( "desc" | "descending") {
- #orderingSpecification = #( [ORDER_SPEC, "desc"] );
- }
- ;
-
-/**
- * A simple-property-path is an IDENT followed by one or more (DOT IDENT) sequences
- */
-simplePropertyPath {
- trace("simplePropertyPath");
- StringBuffer buffer = new StringBuffer();
- }
- : i:IDENT { buffer.append( i.getText() ); }
- ( DOT i2:IDENT { buffer.append( '.').append( i2.getText() ); } )+ {
- #simplePropertyPath = #( [IDENT,buffer.toString()] );
- }
- ;
-
-
-// **** LEXER ******************************************************************
-
-/**
- * Lexer for the <tt>order-by</tt> fragment parser
-
- * @author Steve Ebersole
- * @author Joshua Davis
- */
-class GeneratedOrderByLexer extends Lexer;
-
-options {
- exportVocab=OrderByTemplate;
- testLiterals = false;
- k=2;
- charVocabulary='\u0000'..'\uFFFE'; // Allow any char but \uFFFF (16 bit
-1, ANTLR's EOF character)
- caseSensitive = false;
- caseSensitiveLiterals = false;
-}
-
-// -- Keywords --
-
-OPEN_PAREN: '(';
-CLOSE_PAREN: ')';
-
-COMMA: ',';
-
-HARD_QUOTE: '`';
-
-IDENT options { testLiterals=true; }
- : ID_START_LETTER ( ID_LETTER )*
- ;
-
-protected
-ID_START_LETTER
- : '_'
- | '$'
- | 'a'..'z'
- | '\u0080'..'\ufffe' // HHH-558 : Allow unicode chars in
identifiers
- ;
-
-protected
-ID_LETTER
- : ID_START_LETTER
- | '0'..'9'
- ;
-
-QUOTED_STRING
- : '\'' ( (ESCqs)=> ESCqs | ~'\'' )* '\''
- ;
-
-protected
-ESCqs
- :
- '\'' '\''
- ;
-
-//--- From the Java example grammar ---
-// a numeric literal
-NUM_INT
- {boolean isDecimal=false; Token t=null;}
- : '.' {_ttype = DOT;}
- ( ('0'..'9')+ (EXPONENT)? (f1:FLOAT_SUFFIX {t=f1;})?
- {
- if (t != null && t.getText().toUpperCase().indexOf('F')>=0)
- {
- _ttype = NUM_FLOAT;
- }
- else
- {
- _ttype = NUM_DOUBLE; // assume double
- }
- }
- )?
- | ( '0' {isDecimal = true;} // special case for just '0'
- ( ('x')
- ( // hex
- // the 'e'|'E' and float suffix stuff look
- // like hex digits, hence the (...)+ doesn't
- // know when to stop: ambig. ANTLR resolves
- // it correctly by matching immediately. It
- // is therefore ok to hush warning.
- options { warnWhenFollowAmbig=false; }
- : HEX_DIGIT
- )+
- | ('0'..'7')+ // octal
- )?
- | ('1'..'9') ('0'..'9')* {isDecimal=true;} //
non-zero decimal
- )
- ( ('l') { _ttype = NUM_LONG; }
-
- // only check to see if it's a float if looks like decimal so far
- | {isDecimal}?
- ( '.' ('0'..'9')* (EXPONENT)? (f2:FLOAT_SUFFIX {t=f2;})?
- | EXPONENT (f3:FLOAT_SUFFIX {t=f3;})?
- | f4:FLOAT_SUFFIX {t=f4;}
- )
- {
- if (t != null && t.getText().toUpperCase() .indexOf('F') >= 0)
- {
- _ttype = NUM_FLOAT;
- }
- else
- {
- _ttype = NUM_DOUBLE; // assume double
- }
- }
- )?
- ;
-
-// hexadecimal digit (again, note it's protected!)
-protected
-HEX_DIGIT
- : ('0'..'9'|'a'..'f')
- ;
-
-// a couple protected methods to assist in matching floating point numbers
-protected
-EXPONENT
- : ('e') ('+'|'-')? ('0'..'9')+
- ;
-
-protected
-FLOAT_SUFFIX
- : 'f'|'d'
- ;
-
-WS : ( ' '
- | '\t'
- | '\r' '\n' { newline(); }
- | '\n' { newline(); }
- | '\r' { newline(); }
- )
- {$setType(Token.SKIP);} //ignore this token
- ;
Modified: core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g 2009-01-06 17:14:14 UTC
(rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g 2009-01-06 20:11:13 UTC
(rev 15747)
@@ -74,7 +74,7 @@
BIT = "bit";
BIT_LENGTH = "bit_lenght";
BOTH = "both";
- BY = "by";
+// BY = "by";
CASE = "case";
CAST = "cast";
CHAR = "char";
@@ -112,7 +112,7 @@
FROM = "from";
FULL = "full";
GLOBAL = "global";
- GROUP = "group";
+// GROUP = "group";
HAVING = "having";
HOUR = "hour";
IN = "in";
@@ -150,7 +150,7 @@
ON = "on";
ONLY = "only";
OR = "or";
- ORDER = "order";
+// ORDER = "order";
OUTER = "outer";
OVERLAPS = "overlaps";
PARTIAL = "partial";
@@ -194,6 +194,8 @@
ZONE = "zone";
DOT;
+ ORDER_BY;
+ GROUP_BY;
// synthetic numeric literal types
NUM_INT_LITERAL;
@@ -246,10 +248,81 @@
}
}
-noRules :
+protected
+literal :
+ numericLiteral
+ | characterLiteral
+ | dateLiteral
+ | timeLiteral
+ | timestampLiteral
+ | intervalLiteral
;
+protected
+numericLiteral :
+ UNSIGNED_INTEGER
+ | NUM_INT_LITERAL
+ | NUM_LONG_LITERAL
+ | NUM_DOUBLE_LITERAL
+ | NUM_FLOAT_LITERAL
+;
+protected
+characterLiteral :
+ CHAR_STRING
+ | NATIONAL_CHAR_STRING_LIT
+ | BIT_STRING_LIT
+ | HEX_STRING_LIT
+;
+
+protected
+dateLiteral :
+ DATE^ CHAR_STRING
+;
+
+protected
+timeLiteral :
+ TIME^ CHAR_STRING
+;
+
+protected
+timestampLiteral :
+ TIMESTAMP^ CHAR_STRING
+;
+
+protected
+intervalLiteral :
+ INTERVAL ( PLUS_SIGN | MINUS_SIGN )? CHAR_STRING intervalQualifier
+;
+
+protected
+intervalQualifier :
+ intervalStartField ( TO intervalEndField | )
+ | SECOND ( LEFT_PAREN UNSIGNED_INTEGER ( COMMA UNSIGNED_INTEGER )? RIGHT_PAREN )?
+;
+
+protected
+intervalStartField :
+ nonSecondDatetimeField ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+;
+
+protected
+intervalEndField :
+ nonSecondDatetimeField
+ | SECOND ( LEFT_PAREN UNSIGNED_INTEGER RIGHT_PAREN )?
+;
+
+protected
+nonSecondDatetimeField :
+ YEAR
+ | MONTH
+ | DAY
+ | HOUR
+ | MINUTE
+;
+
+
+
// Lexer
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
@@ -349,9 +422,16 @@
| BIT_STRING_LIT {$setType(BIT_STRING_LIT);}
| HEX_STRING_LIT {$setType(HEX_STRING_LIT);}
)
- | (SIMPLE_LETTER | '_' | '$') (SIMPLE_LETTER | '_' | '$'
| '0'..'9')* {
+ | id:ID { setPossibleIdentifier( true ); } (
+ { id.getText().equalsIgnoreCase("order") }? (WHITESPACE)+ "by"!
{ setPossibleIdentifier( false ); $setType(ORDER_BY); $setText("order by"); }
+ | { id.getText().equalsIgnoreCase("group") }? (WHITESPACE)+
"by"! { setPossibleIdentifier( false ); $setType(GROUP_BY); $setText("group
by"); }
+ )?
+;
+
+protected
+ID options { testLiterals=true; } :
+ (SIMPLE_LETTER | '_' | '$') (SIMPLE_LETTER | '_' | '$' |
'0'..'9')* {
setPossibleIdentifier( true );
-// $setType( testLiteralsTable( IDENT ) );
}
;
Deleted:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/ASTFactoryImpl.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -1,42 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.hql.ast.phase.parse;
-
-import antlr.ASTFactory;
-
-import org.hibernate.sql.ast.common.Node;
-
-/**
- * TODO : javadoc
- *
- * @author Steve Ebersole
- */
-public class ASTFactoryImpl extends ASTFactory {
- /**
- * {@inheritDoc}
- */
- public Class getASTNodeType(int tokenType) {
- return Node.class;
- }
-}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -80,7 +80,7 @@
import org.hibernate.sql.SelectFragment;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.sql.Template;
-import org.hibernate.sql.ordering.antlr.ColumnMapper;
+import org.hibernate.sql.ast.ordering.ColumnMapper;
import org.hibernate.type.AbstractComponentType;
import org.hibernate.type.CollectionType;
import org.hibernate.type.EntityType;
Modified: core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/Template.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -30,9 +30,9 @@
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.function.SQLFunctionRegistry;
import org.hibernate.util.StringHelper;
-import org.hibernate.sql.ordering.antlr.ColumnMapper;
-import org.hibernate.sql.ordering.antlr.TranslationContext;
-import org.hibernate.sql.ordering.antlr.OrderByFragmentTranslator;
+import org.hibernate.sql.ast.ordering.ColumnMapper;
+import org.hibernate.sql.ast.ordering.TranslationContext;
+import org.hibernate.sql.ast.ordering.OrderByFragmentTranslator;
import org.hibernate.engine.SessionFactoryImplementor;
/**
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/DetailedSemanticException.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -1,36 +1,79 @@
-// $Id: DetailedSemanticException.java 5690 2005-02-12 20:27:50Z pgmjsd $
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
package org.hibernate.sql.ast;
import antlr.SemanticException;
+import antlr.Token;
+import antlr.collections.AST;
import java.io.PrintStream;
import java.io.PrintWriter;
/**
- * Thrown when a call to the underlying Hibernate engine fails, indicating
- * some form of semantic exception (e.g. a class name was not found in the
- * current mappings, etc.).
+ * Thrown when a call to the underlying Hibernate engine fails, indicating some form of
semantic exception (e.g. an
+ * entity name was not found in the mappings, etc.).
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
*/
public class DetailedSemanticException extends SemanticException {
private Throwable cause;
- private boolean showCauseMessage = true;
public DetailedSemanticException(String message) {
super( message );
}
- public DetailedSemanticException(String s, Throwable e) {
- super( s );
+ public DetailedSemanticException(String message, Token token) {
+ super( message, token.getFilename(), token.getLine(), token.getColumn() );
+ }
+
+ public DetailedSemanticException(String message, AST ast) {
+ super( message, "", ast.getLine(), ast.getColumn() );
+ }
+
+ public DetailedSemanticException(String message, Throwable e) {
+ this( message );
cause = e;
}
+ public DetailedSemanticException(String message, Token token, Throwable e) {
+ this( message, token );
+ cause = e;
+ }
+
+ public DetailedSemanticException(String message, AST ast, Throwable e) {
+ this( message, ast );
+ cause = e;
+ }
+
/**
* Converts everything to a string.
*
* @return a string.
*/
public String toString() {
- if ( cause == null || ( !showCauseMessage ) ) {
+ if ( cause == null ) {
return super.toString();
}
else {
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/JoinType.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -3,6 +3,8 @@
import java.io.Serializable;
import java.util.HashMap;
+import org.hibernate.sql.ast.util.ASTUtil;
+
/**
* Represents a canonical join type.
* <p/>
@@ -59,4 +61,26 @@
private Object readResolve() {
return INSTANCES.get( name );
}
+
+ public static JoinType resolve(Node node) {
+ switch ( node.getType() ) {
+ case Sql92TokenTypes.INNER :
+ return JoinType.INNER;
+ case Sql92TokenTypes.LEFT :
+ return JoinType.LEFT;
+ case Sql92TokenTypes.RIGHT :
+ return JoinType.RIGHT;
+ case Sql92TokenTypes.CROSS :
+ return JoinType.CROSS;
+ case Sql92TokenTypes.FULL :
+ return JoinType.FULL;
+ default :
+ throw new IllegalArgumentException(
+ "Cannot resolve join-type node [type=" +
+ ASTUtil.getTokenTypeName( Sql92TokenTypes.class, node.getType() ) +
+ ", text=" + node.getText() +
+ "]"
+ );
+ }
+ }
}
Deleted:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -1,92 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
- * indicated by the @author tags or express copyright attribution
- * statements applied by the authors. All third-party contributions are
- * distributed under license by Red Hat Middleware LLC.
- *
- * This copyrighted material is made available to anyone wishing to use, modify,
- * copy, or redistribute it subject to the terms and conditions of the GNU
- * Lesser General Public License, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this distribution; if not, write to:
- * Free Software Foundation, Inc.
- * 51 Franklin Street, Fifth Floor
- * Boston, MA 02110-1301 USA
- */
-package org.hibernate.sql.ast.common;
-
-import antlr.Token;
-import antlr.collections.AST;
-
-/**
- * Basic AST node
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public class Node extends antlr.CommonAST {
- private String filename;
- private int line;
- private int column;
-
- public Node() {
- super();
- }
-
- public Node(Token tok) {
- super( tok ); // NOTE: This will call initialize(tok)!
- }
-
- public void initialize(Token token) {
- super.initialize( token );
- // Propagate line/column information from the lexer during
- // stream parsing.
- filename = token.getFilename();
- line = token.getLine();
- column = token.getColumn();
- }
-
- public void initialize(AST ast) {
- super.initialize( ast );
- if ( ast instanceof Node ) {
- // Propagate line/column information from the source AST during tree walking.
- transferTrackingInfo( ( Node ) ast );
- }
- }
-
- public void transferTrackingInfo(AST ast) {
- if ( ast instanceof Node ) {
- transferTrackingInfo( ( Node ) ast );
- }
- else {
- line = ast.getLine();
- column = ast.getColumn();
- }
- }
-
- public void transferTrackingInfo(Node node) {
- filename = node.filename;
- line = node.line;
- column = node.column;
- }
-
- public String getFilename() {
- return filename;
- }
-
- public int getLine() {
- return line;
- }
-
- public int getColumn() {
- return column;
- }
-}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/Node.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,104 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.common;
+
+import antlr.Token;
+import antlr.collections.AST;
+
+/**
+ * Basic AST node
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class Node extends antlr.CommonAST {
+ private String filename;
+ private int line;
+ private int column;
+
+ public Node() {
+ super();
+ }
+
+ public Node(Token tok) {
+ super( tok ); // NOTE: This will call initialize(tok)!
+ }
+
+ /**
+ * Retrieve the textual representation of a node to be used in the resulting sql.
+ * <p/>
+ * This is intended for subclasses to override to allow certain nodes to provide their
own renderable representation
+ * instead of the default {@link antlr.collections.AST#getText()}.
+ *
+ * @return The renderable text.
+ */
+ public String getRenderableText() {
+ return getText();
+ }
+
+ public void initialize(Token token) {
+ super.initialize( token );
+ // Propagate line/column information from the lexer during
+ // stream parsing.
+ filename = token.getFilename();
+ line = token.getLine();
+ column = token.getColumn();
+ }
+
+ public void initialize(AST ast) {
+ super.initialize( ast );
+ if ( ast instanceof Node ) {
+ // Propagate line/column information from the source AST during tree walking.
+ transferTrackingInfo( ( Node ) ast );
+ }
+ }
+
+ public void transferTrackingInfo(AST ast) {
+ if ( ast instanceof Node ) {
+ transferTrackingInfo( ( Node ) ast );
+ }
+ else {
+ line = ast.getLine();
+ column = ast.getColumn();
+ }
+ }
+
+ public void transferTrackingInfo(Node node) {
+ filename = node.filename;
+ line = node.line;
+ column = node.column;
+ }
+
+ public String getFilename() {
+ return filename;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/NodeFactory.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.common;
+
+import antlr.ASTFactory;
+
+/**
+ * An {@link ASTFactory} which includes line/column tracking information into its
generated
+ * {@link antlr.collections.AST nodes}.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class NodeFactory extends ASTFactory {
+ /**
+ * Determine the default {@link antlr.collections.AST node} class to use. Used from
within
+ * {@link #getASTNodeType(int)} when no specific override is defined/needed for a
particular token type.
+ *
+ * @return The default {@link antlr.collections.AST node} class to use
+ */
+ protected Class determineDefaultNodeClass() {
+ return Node.class;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Class getASTNodeType(int tokenType) {
+ return determineDefaultNodeClass();
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/common/PanicException.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -26,7 +26,7 @@
import org.hibernate.HibernateException;
/**
- * Thrown to indicate a panic situation ossuring in a lexer.
+ * Thrown to indicate a panic situation occuring in a lexer.
*
* @author Steve Ebersole
*/
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/CollationSpecification.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/CollationSpecification.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,36 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models a collation specification (<tt>COLLATE</tt> using a specific
character-set) within a
+ * {@link SortSpecification}.
+ *
+ * @author Steve Ebersole
+ */
+public class CollationSpecification extends Node {
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/ColumnMapper.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/ColumnMapper.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Contract for mapping a (an assumed) property reference to its columns.
+ *
+ * @author Steve Ebersole
+ */
+public interface ColumnMapper {
+ /**
+ * Resolve the property reference to its underlying columns.
+ *
+ * @param reference The property reference name.
+ *
+ * @return The underlying columns, or null if the property reference is unknown.
+ *
+ * @throws HibernateException Generally indicates that the property reference is unkown;
interpretation is the
+ * same as a null return.
+ */
+ public String[] map(String reference) throws HibernateException;
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/Factory.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/Factory.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,55 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.NodeFactory;
+
+/**
+ * Acts as a {@link NodeFactory} for injecting our specific AST node classes into the
Antlr generated trees.
+ *
+ * @author Steve Ebersole
+ */
+public class Factory extends NodeFactory implements OrderByTemplateTokenTypes {
+ /**
+ * {@inheritDoc}
+ */
+ public Class getASTNodeType(int i) {
+ switch ( i ) {
+ case ORDER_BY:
+ return OrderByFragment.class;
+ case SORT_SPEC:
+ return SortSpecification.class;
+ case ORDER_SPEC:
+ return OrderingSpecification.class;
+ case COLLATE:
+ return CollationSpecification.class;
+ case SORT_KEY:
+ return SortKey.class;
+ default:
+ return Node.class;
+ }
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragment.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragment.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Represents a parsed <tt>order-by</tt> mapping fragment. This holds the
tree of all {@link SortSpecification}s.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragment extends Node {
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentParser.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentParser.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,214 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import java.util.ArrayList;
+
+import antlr.TokenStream;
+import antlr.CommonAST;
+import antlr.TokenStreamException;
+import antlr.collections.AST;
+
+import org.hibernate.sql.Template;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extension of the Antlr-generated parser for the purpose of adding our custom parsing
behavior.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentParser extends GeneratedOrderByFragmentParser {
+ private static final Logger log = LoggerFactory.getLogger( OrderByFragmentParser.class
);
+
+ private final TranslationContext context;
+ private int traceDepth = 0;
+
+ public OrderByFragmentParser(TokenStream lexer, TranslationContext context) {
+ super( lexer );
+ super.setASTFactory( new Factory() );
+ this.context = context;
+ }
+
+
+ // handle trace logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void traceIn(String ruleName) throws TokenStreamException {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = StringHelper.repeat( "-", (traceDepth++ * 2) ) +
"->";
+ trace( prefix + ruleName );
+ }
+
+ public void traceOut(String ruleName) throws TokenStreamException {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = "<-" + StringHelper.repeat( "-", (--traceDepth *
2) );
+ trace( prefix + ruleName );
+ }
+
+ private void trace(String msg) {
+ log.trace( msg );
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST quotedIdentifier(AST ident) {
+ return getASTFactory().create(
+ IDENT,
+ Template.TEMPLATE + "." + context.getDialect().quote( '`' +
ident.getText() + '`' )
+ );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST quotedString(AST ident) {
+ return getASTFactory().create( IDENT, context.getDialect().quote( ident.getText() ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected boolean isFunctionName(AST ast) {
+ return context.getSqlFunctionRegistry().hasFunction( ast.getText() );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST resolveFunction(AST ast) {
+ AST child = ast.getFirstChild();
+ assert "{param list}".equals( child.getText() );
+ child = child.getFirstChild();
+
+ final String functionName = ast.getText();
+ final SQLFunction function = context.getSqlFunctionRegistry().findSQLFunction(
functionName );
+ if ( function == null ) {
+ String text = functionName;
+ if ( child != null ) {
+ text += '(';
+ while ( child != null ) {
+ text += child.getText();
+ child = child.getNextSibling();
+ if ( child != null ) {
+ text += ", ";
+ }
+ }
+ text += ')';
+ }
+ return getASTFactory().create( IDENT, text );
+ }
+ else {
+ ArrayList expressions = new ArrayList();
+ while ( child != null ) {
+ expressions.add( child.getText() );
+ child = child.getNextSibling();
+ }
+ final String text = function.render( expressions, context.getSessionFactory() );
+ return getASTFactory().create( IDENT, text );
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST resolveIdent(AST ident) {
+ String text = ident.getText();
+ String[] replacements;
+ try {
+ replacements = context.getColumnMapper().map( text );
+ }
+ catch( Throwable t ) {
+ replacements = null;
+ }
+
+ if ( replacements == null || replacements.length == 0 ) {
+ return getASTFactory().create( IDENT, Template.TEMPLATE + "." + text );
+ }
+ else if ( replacements.length == 1 ) {
+ return getASTFactory().create( IDENT, Template.TEMPLATE + "." +
replacements[0] );
+ }
+ else {
+ final AST root = getASTFactory().create( IDENT_LIST, "{ident list}" );
+ for ( int i = 0; i < replacements.length; i++ ) {
+ final String identText = Template.TEMPLATE + '.' + replacements[i];
+ root.addChild( getASTFactory().create( IDENT, identText ) );
+ }
+ return root;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected AST postProcessSortSpecification(AST sortSpec) {
+ assert SORT_SPEC == sortSpec.getType();
+ SortSpecification sortSpecification = ( SortSpecification ) sortSpec;
+ AST sortKey = sortSpecification.getSortKey();
+ if ( IDENT_LIST == sortKey.getFirstChild().getType() ) {
+ AST identList = sortKey.getFirstChild();
+ AST ident = identList.getFirstChild();
+ AST holder = new CommonAST();
+ do {
+ holder.addChild(
+ createSortSpecification(
+ ident,
+ sortSpecification.getCollation(),
+ sortSpecification.getOrdering()
+ )
+ );
+ ident = ident.getNextSibling();
+ } while ( ident != null );
+ sortSpec = holder.getFirstChild();
+ }
+ return sortSpec;
+ }
+
+ private SortSpecification createSortSpecification(
+ AST ident,
+ CollationSpecification collationSpecification,
+ OrderingSpecification orderingSpecification) {
+ AST sortSpecification = getASTFactory().create( SORT_SPEC, "{{sort
specification}}" );
+ AST sortKey = getASTFactory().create( SORT_KEY, "{{sort key}}" );
+ AST newIdent = getASTFactory().create( ident.getType(), ident.getText() );
+ sortKey.setFirstChild( newIdent );
+ sortSpecification.setFirstChild( sortKey );
+ if ( collationSpecification != null ) {
+ sortSpecification.addChild( collationSpecification );
+ }
+ if ( orderingSpecification != null ) {
+ sortSpecification.addChild( orderingSpecification );
+ }
+ return ( SortSpecification ) sortSpecification;
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentRenderer.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentRenderer.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,79 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentRenderer extends GeneratedOrderByFragmentRenderer {
+ private static final Logger log = LoggerFactory.getLogger( OrderByFragmentRenderer.class
);
+
+ protected void out(AST ast) {
+ out( ( ( Node ) ast ).getRenderableText() );
+ }
+
+ // handle trace logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private final ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
+ private int traceDepth = 0;
+
+ public void traceIn(String ruleName, AST tree) {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = StringHelper.repeat( '-', (traceDepth++ * 2) ) + "->
";
+ String traceText = ruleName + " (" + buildTraceNodeName(tree) +
")";
+ trace( prefix + traceText );
+ }
+
+ private String buildTraceNodeName(AST tree) {
+ return tree == null
+ ? "???"
+ : tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) +
"]";
+ }
+
+ public void traceOut(String ruleName, AST tree) {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth *
2) ) + " ";
+ trace( prefix + ruleName );
+ }
+
+ private void trace(String msg) {
+ log.trace( msg );
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderByFragmentTranslator.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderByFragmentTranslator.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import java.io.StringReader;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.hql.ast.util.ASTPrinter;
+
+/**
+ * A translator which coordinates translation of an <tt>order-by</tt>
mapping.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByFragmentTranslator {
+ private static final Logger log = LoggerFactory.getLogger(
OrderByFragmentTranslator.class );
+
+ public final TranslationContext context;
+
+ public OrderByFragmentTranslator(TranslationContext context) {
+ this.context = context;
+ }
+
+ /**
+ * The main contract, performing the transaction.
+ *
+ * @param fragment The <tt>order-by</tt> mapping fragment to be translated.
+ *
+ * @return The translated fragment.
+ */
+ public String render(String fragment) {
+ GeneratedOrderByLexer lexer = new GeneratedOrderByLexer( new StringReader( fragment )
);
+ OrderByFragmentParser parser = new OrderByFragmentParser( lexer, context );
+ try {
+ parser.orderByFragment();
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch ( Throwable t ) {
+ throw new HibernateException( "Unable to parse order-by fragment", t );
+ }
+
+ if ( log.isTraceEnabled() ) {
+ ASTPrinter printer = new ASTPrinter( OrderByTemplateTokenTypes.class );
+ log.trace( printer.showAsString( parser.getAST(), "--- {order-by fragment}
---" ) );
+ }
+
+ GeneratedOrderByFragmentRenderer renderer = new GeneratedOrderByFragmentRenderer();
+ try {
+ renderer.orderByFragment( parser.getAST() );
+ }
+ catch ( HibernateException e ) {
+ throw e;
+ }
+ catch ( Throwable t ) {
+ throw new HibernateException( "Unable to render parsed order-by fragment", t
);
+ }
+
+ return renderer.getRenderedFragment();
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/OrderingSpecification.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/OrderingSpecification.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,72 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models an ordering specification (<tt>ASCENDING</tt> or
<tt>DESCENDING</tt>) within a {@link SortSpecification}.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderingSpecification extends Node {
+ public static class Ordering {
+ public static final Ordering ASCENDING = new Ordering( "asc" );
+ public static final Ordering DESCENDING = new Ordering( "desc" );
+
+ private final String name;
+
+ private Ordering(String name) {
+ this.name = name;
+ }
+ }
+
+ private boolean resolved;
+ private Ordering ordering;
+
+ public Ordering getOrdering() {
+ if ( !resolved ) {
+ ordering = resolve( getText() );
+ resolved = true;
+ }
+ return ordering;
+ }
+
+ private static Ordering resolve(String text) {
+ if ( Ordering.ASCENDING.name.equals( text ) ) {
+ return Ordering.ASCENDING;
+ }
+ else if ( Ordering.DESCENDING.name.equals( text ) ) {
+ return Ordering.DESCENDING;
+ }
+ else {
+ throw new IllegalStateException( "Unknown ordering [" + text + "]"
);
+ }
+ }
+
+ public String getRenderableText() {
+ return getOrdering().name;
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/SortKey.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortKey.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,36 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models the container node for the <tt>sort key</tt>, which is the term
given by the ANSI SQL specification to the
+ * expression upon which to sort for each {@link SortSpecification}
+ *
+ * @author Steve Ebersole
+ */
+public class SortKey extends Node {
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/SortSpecification.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/SortSpecification.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,82 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Models each sorting exprersion.
+ *
+ * @author Steve Ebersole
+ */
+public class SortSpecification extends Node {
+ /**
+ * Locate the specified {@link SortKey}.
+ *
+ * @return The sort key.
+ */
+ public SortKey getSortKey() {
+ return ( SortKey ) getFirstChild();
+ }
+
+ /**
+ * Locate the specified <tt>collation specification</tt>, if one.
+ *
+ * @return The <tt>collation specification</tt>, or null if none was
specified.
+ */
+ public CollationSpecification getCollation() {
+ AST possible = getSortKey().getNextSibling();
+ return possible != null && OrderByTemplateTokenTypes.COLLATE ==
possible.getType()
+ ? ( CollationSpecification ) possible
+ : null;
+ }
+
+ /**
+ * Locate the specified <tt>ordering specification</tt>, if one.
+ *
+ * @return The <tt>ordering specification</tt>, or null if none was
specified.
+ */
+ public OrderingSpecification getOrdering() {
+ // IMPL NOTE : the ordering-spec would be either the 2nd or 3rd child (of the overall
sort-spec), if it existed,
+ // depending on whether a collation-spec was specified.
+
+ AST possible = getSortKey().getNextSibling();
+ if ( possible == null ) {
+ // There was no sort-spec parts specified other then the sort-key so there can be no
ordering-spec...
+ return null;
+ }
+
+ if ( OrderByTemplateTokenTypes.COLLATE == possible.getType() ) {
+ // the 2nd child was a collation-spec, so we need to check the 3rd child instead.
+ possible = possible.getNextSibling();
+ }
+
+ return possible != null && OrderByTemplateTokenTypes.ORDER_SPEC ==
possible.getType()
+ ? ( OrderingSpecification ) possible
+ : null;
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java
(from rev 15683,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ordering/antlr/TranslationContext.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/ordering/TranslationContext.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,64 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.sql.ast.ordering;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+
+/**
+ * Contract for contextual information required to perform translation.
+*
+* @author Steve Ebersole
+*/
+public interface TranslationContext {
+ /**
+ * Retrieves the <tt>session factory</tt> for this context.
+ *
+ * @return The <tt>session factory</tt>
+ */
+ public SessionFactoryImplementor getSessionFactory();
+
+ /**
+ * Retrieves the <tt>dialect</tt> for this context.
+ *
+ * @return The <tt>dialect</tt>
+ */
+ public Dialect getDialect();
+
+ /**
+ * Retrieves the <tt>SQL function registry/tt> for this context.
+ *
+ * @return The SQL function registry.
+ */
+ public SQLFunctionRegistry getSqlFunctionRegistry();
+
+ /**
+ * Retrieves the <tt>column mapper</tt> for this context.
+ *
+ * @return The <tt>column mapper</tt>
+ */
+ public ColumnMapper getColumnMapper();
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/ASTFactoryImpl.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,103 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+import antlr.Token;
+
+import org.hibernate.sql.ast.common.NodeFactory;
+
+/**
+ * AST factory for the resolve phase of HQL query translation.
+ *
+ * @author Steve Ebersole
+ */
+public class ASTFactoryImpl extends NodeFactory implements HqlNormalizeTokenTypes {
+ private final NormalizationContext resolutionContext;
+
+ public ASTFactoryImpl(NormalizationContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ public Class getASTNodeType(int tokenType) {
+ switch ( tokenType ) {
+ case IDENT :
+ return Ident.class;
+ case ENTITY_PERSISTER_REF :
+ return EntityPersisterReference.class;
+ case COLLECTION_PERSISTER_REF :
+ return CollectionPersisterReference.class;
+ case JOIN :
+ return Join.class;
+ case ALIAS_REF :
+ return PersisterAliasReference.class;
+ case PROPERTY_REF :
+ return PropertyReference.class;
+ case INSERT :
+ return InsertStatement.class;
+ case UPDATE :
+ return UpdateStatement.class;
+ case DELETE :
+ return DeleteStatement.class;
+ case QUERY :
+ return SelectStatement.class;
+ case QUERY_SPEC :
+ return QuerySpec.class;
+ case SELECT_ITEM :
+ return SelectItem.class;
+ default:
+ return determineDefaultNodeClass();
+ }
+ }
+
+ protected AST createUsingCtor(Token token, String className) {
+ return super.createUsingCtor( token, className );
+ }
+
+ /**
+ * Instantiate the AST node of the given type.
+ *
+ * @param c The AST class to instantiate.
+ * @return The instantiated and initialized node.
+ */
+ protected AST create(Class c) {
+ AST ast = super.create( c );
+ if ( ast != null ) {
+ initialize( ast );
+ }
+ return ast;
+ }
+
+ /**
+ * Perform any optional requested initializatio on the node. In this impl, that means
to look at the node's
+ * interfaces.
+ *
+ * @param ast The node
+ */
+ protected void initialize(AST ast) {
+ if ( ast instanceof NormalizationContextAwareNode ) {
+ ( ( NormalizationContextAwareNode ) ast ).injectResolutionContext( resolutionContext
);
+ }
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AbstractPersisterReference.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,60 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.Map;
+import java.util.HashMap;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Base class for {@link PersisterReference} implementations. Mainly it centralizes
handling
+ * of reusable proerty joins.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPersisterReference extends Node implements
PersisterReference {
+ private Map reusablePropertyJoins = new HashMap();
+
+ /**
+ * {@inheritDoc}
+ */
+ public Join locateReusablePropertyJoin(String path) {
+ return ( Join ) reusablePropertyJoins.get( path );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void registerReusablePropertyJoin(String path, Join join) {
+ reusablePropertyJoins.put( path, join );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersisterReference locatePersisterReference() {
+ return this;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/AliasBuilder.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * Handles generating synthetic or implicit aliases.
+ *
+ * @author Steve Ebersole
+ */
+public class AliasBuilder {
+ private int unaliasedCount = 0;
+
+ /**
+ * Builds a unique implicit alias.
+ *
+ * @return The generated alias.
+ */
+ public synchronized String buildUniqueImplicitAlias() {
+ return "<gen:" + unaliasedCount++ + ">";
+ }
+
+ /**
+ * Determine if the given alias is implicit.
+ *
+ * @param alias The alias to check
+ * @return True/false.
+ */
+ public static boolean isImplicitAlias(String alias) {
+ return alias == null || ( alias.startsWith( "<gen:" ) &&
alias.endsWith( ">" ) );
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/CollectionPersisterReference.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,146 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.AssertionFailure;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.ComponentType;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.collection.CollectionPropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+
+/**
+ * Represents a reference to an {@link
org.hibernate.persister.collection.CollectionPersister}
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionPersisterReference extends AbstractPersisterReference
+ implements NormalizationContextAwareNode, DisplayableNode {
+ private NormalizationContext resolutionContext;
+ private transient QueryableCollection persister;
+ private transient CollectionPropertyMapping propertyMapping;
+
+ /**
+ * Retrieve the collection "role" identifying the underlying {@link
org.hibernate.persister.collection.CollectionPersister}
+ *
+ * @return The collection role
+ */
+ public String getRole() {
+ return getFirstChild().getText();
+ }
+
+ public String getAlias() {
+ return getFirstChild().getNextSibling().getText();
+ }
+
+ public String getName() {
+ return getRole();
+ }
+
+ public boolean isCollection() {
+ return true;
+ }
+
+ /**
+ * Retrieve a reference to the underlying collection persister.
+ *
+ * @return The collection persister.
+ */
+ public QueryableCollection getCollectionPersister() {
+ if ( persister == null ) {
+ persister = ( QueryableCollection ) getSessionFactory().getCollectionPersister(
getRole() );
+ }
+ return persister;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AssociationType getPersisterType() {
+ return ( AssociationType ) getCollectionPersister().getElementType();
+ }
+
+ public Type getPropertyType(String propertyName) {
+ // this should not be called for "collection properties" (i.e., SIZE,
MAXELEMENT, etc)...
+ Type elementType = getCollectionPersister().getElementType();
+ if ( elementType.isAssociationType() ) {
+ // a collection of entities
+ EntityType elementEntityType = ( EntityType ) elementType;
+ try {
+ Queryable elementEntityPersister = ( Queryable ) elementEntityType
+ .getAssociatedJoinable( getSessionFactory() );
+ return elementEntityPersister.getPropertyType( propertyName );
+ }
+ catch( Throwable ignore ) {
+ // ignore
+ }
+ }
+ else if ( elementType.isComponentType() ) {
+ ComponentType elementComponentType = ( ComponentType ) elementType;
+ String[] subPropertyNames = elementComponentType.getPropertyNames();
+ for ( int i = 0; i < subPropertyNames.length; i++ ) {
+ if ( subPropertyNames[i].equals( propertyName ) ) {
+ return elementComponentType.getSubtypes()[i];
+ }
+ }
+ }
+ return null;
+ }
+
+ public boolean containsProperty(String propertyName) {
+ return getPropertyType( propertyName ) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void injectResolutionContext(NormalizationContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ private final SessionFactoryImplementor getSessionFactory() {
+ if ( resolutionContext == null ) {
+ throw new AssertionFailure( "resolution context was null on attempt to retrieve
session factory reference" );
+ }
+ return resolutionContext.getSessionFactoryImplementor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "CollectionPersisterReference [role=" + getRole()
+ + ",alias=" + getAlias()
+ + ",element-type=" + getCollectionPersister().getElementType().getName()
+ + "]";
+ }
+
+ public String getDisplayText() {
+ return getRole() + " (" + getAlias() + ")";
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DeleteStatement.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing <tt>DELETE</tt> statements
+ *
+ * @author Steve Ebersole
+ */
+public class DeleteStatement extends Node implements Statement {
+ public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext
normalizationContext) {
+ return new BasicPathNormalizationStrategySupport( normalizationContext ) {
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException(
+ "delete statement cannot contain implicit join path expressions"
+ );
+ }
+ };
+ }
+}
\ No newline at end of file
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/DuplicateAliasException.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,44 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates that a query attempted to define the same alias more than once.
+ *
+ * @author Steve Ebersole
+ */
+public class DuplicateAliasException extends HibernateException {
+ private final String alias;
+
+ public DuplicateAliasException(String alias) {
+ super( "Attempt to register alias [" + alias + "] multiple times"
);
+ this.alias = alias;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/EntityPersisterReference.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,151 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.Iterator;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.sql.ast.util.ASTChildIterator;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.AssertionFailure;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.persister.entity.Queryable;
+
+/**
+ * Represents a reference to an {@link org.hibernate.persister.entity.EntityPersister}
+ *
+ * @author Steve Ebersole
+ */
+public class EntityPersisterReference extends AbstractPersisterReference
+ implements NormalizationContextAwareNode, DisplayableNode {
+ private NormalizationContext resolutionContext;
+ private transient Queryable persister;
+
+ /**
+ * Retrieve the entity name of the underlying {@link
org.hibernate.persister.entity.EntityPersister}
+ *
+ * @return The entity name
+ */
+ public String getEntityName() {
+ return getFirstChild().getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getAlias() {
+ return getFirstChild().getNextSibling().getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getName() {
+ return getEntityName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isCollection() {
+ return false;
+ }
+
+ /**
+ * Retrieves a reference to the underlying entity persister.
+ *
+ * @return The underlying entity persister.
+ */
+ public Queryable getEntityPersister() {
+ if ( persister == null ) {
+ persister = ( Queryable ) getSessionFactory().getEntityPersister( getEntityName() );
+ }
+ return persister;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AssociationType getPersisterType() {
+ return ( AssociationType ) getEntityPersister().getType();
+ }
+
+ public Type getPropertyType(String propertyName) {
+ try {
+ return getEntityPersister().getPropertyType( propertyName );
+ }
+ catch( Throwable ignore ) {
+ return null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean containsProperty(String propertyName) {
+ return getPropertyType( propertyName ) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void injectResolutionContext(NormalizationContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ private SessionFactoryImplementor getSessionFactory() {
+ if ( resolutionContext == null ) {
+ throw new AssertionFailure( "resolution context was null on attempt to retrieve
session factory reference" );
+ }
+ return resolutionContext.getSessionFactoryImplementor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "EntityPersisterReference [entity-name=" + getEntityName() +
",alias=" + getAlias() + "]";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getDisplayText() {
+ return getEntityName() + " (" + getAlias() + ")";
+ }
+
+ public Iterator locateJoins() {
+ AST firstJoin = getFirstChild().getNextSibling().getNextSibling();
+ if ( firstJoin == null ) {
+ return EmptyIterator.INSTANCE;
+ }
+ else {
+ return new ASTChildIterator( firstJoin );
+ }
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HierarchicalPersisterReferenceContext.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,98 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * Defines a hierarchical representation of a persister reference context.
+ * <p/>
+ * Generally speaking this notion should really only hold for SELECT statements. Does
not make sense for
+ * INSERT or UPDATE or DELETE statements to have a parent, as that would mean they are
being used as in a subqquery
+ * (certainly, however, it makes sense for these to *be the parent* context...).
+ *
+ * @author Steve Ebersole
+ */
+public class HierarchicalPersisterReferenceContext extends RootPersisterReferenceContext
implements PersisterReferenceContext {
+ private final PersisterReferenceContext parent;
+
+ public HierarchicalPersisterReferenceContext(PersisterReferenceContext parent) {
+ super();
+ if ( parent == null ) {
+ throw new IllegalArgumentException( "Parent PersisterReferenceContext cannot be
null!" );
+ }
+ this.parent = parent;
+ }
+
+ /**
+ * Get the parent context of this context.
+ *
+ * @return Our parent context.
+ */
+ public PersisterReferenceContext getParent() {
+ return parent;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public boolean isContainedAlias(String alias) {
+ return super.isContainedAlias( alias ) || getParent().isContainedAlias( alias );
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public boolean isContainedExposedProperty(String propertyName) {
+ return super.isContainedExposedProperty( propertyName ) ||
getParent().isContainedExposedProperty( propertyName );
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public PersisterReference locatePersisterReferenceByAlias(String alias) {
+ PersisterReference persisterReference = super.locatePersisterReferenceByAlias( alias
);
+ if ( persisterReference == null ) {
+ persisterReference = getParent().locatePersisterReferenceByAlias( alias );
+ }
+ return persisterReference;
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Overriden to project the lookup to our parent if not found locally.
+ */
+ public PersisterReference locatePersisterReferenceExposingProperty(String propertyName)
{
+ PersisterReference persisterReference = super.locatePersisterReferenceExposingProperty(
propertyName );
+ if ( persisterReference == null ) {
+ persisterReference = getParent().locatePersisterReferenceExposingProperty(
propertyName );
+ }
+ return persisterReference;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/HqlNormalizer.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,374 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.util.ParseErrorHandler;
+import org.hibernate.sql.ast.util.ErrorCounter;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.common.JoinType;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.FromClausePathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.SelectClausePathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.OnFragmentPathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.WithFragmentPathNormalizationStrategy;
+import org.hibernate.QueryException;
+import org.hibernate.MappingException;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategyStack;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.util.StringHelper;
+
+import antlr.RecognitionException;
+import antlr.ASTFactory;
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class HqlNormalizer extends GeneratedHqlNormalizer implements NormalizationContext
{
+ private static final Logger log = LoggerFactory.getLogger( HqlNormalizer.class );
+
+ private final SessionFactoryImplementor sessionFactory;
+ private final PersisterReferenceBuilder persisterReferenceBuilder;
+ private final ParseErrorHandler parseErrorHandler = new ErrorCounter();
+ private final ASTPrinter printer = new ASTPrinter( HqlNormalizeTokenTypes.class );
+ private final AliasBuilder aliasBuilder = new AliasBuilder();
+ private final PathNormalizationStrategyStack pathNormalizationStrategyStack = new
PathNormalizationStrategyStack();
+
+ private int traceDepth = 0;
+
+ public HqlNormalizer(SessionFactoryImplementor sessionFactory) {
+ super();
+ this.sessionFactory = sessionFactory;
+ this.persisterReferenceBuilder = new PersisterReferenceBuilder( this );
+ super.setASTFactory( new ASTFactoryImpl( this ) );
+ }
+
+ public ASTPrinter getPrinter() {
+ return printer;
+ }
+
+
+ // overrides of Antlr infastructure methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void reportError(RecognitionException e) {
+ getParseErrorHandler().reportError( e );
+ }
+
+ public void reportError(String s) {
+ getParseErrorHandler().reportError( s );
+ }
+
+ public void reportWarning(String s) {
+ getParseErrorHandler().reportWarning( s );
+ }
+
+ public ParseErrorHandler getParseErrorHandler() {
+ return parseErrorHandler;
+ }
+
+ static public void panic() {
+ //overriden to avoid System.exit
+ throw new QueryException( "Parser: panic" );
+ }
+
+ public void setASTFactory(ASTFactory astFactory) {
+ throw new UnsupportedOperationException( "not allowed!" );
+ }
+
+
+ // Resolution state
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private PersisterReferenceContext currentPersisterReferenceContext;
+
+ public PersisterReferenceContext getCurrentPersisterReferenceContext() {
+ return currentPersisterReferenceContext;
+ }
+
+ protected void pushStatement(AST statementNode) {
+ if ( currentPersisterReferenceContext == null ) {
+ currentPersisterReferenceContext = new RootPersisterReferenceContext();
+ }
+ else {
+ currentPersisterReferenceContext = new HierarchicalPersisterReferenceContext(
currentPersisterReferenceContext );
+ }
+
+ pathNormalizationStrategyStack.push( new BasicPathNormalizationStrategySupport( this )
);
+ }
+
+ protected void popStatement() {
+ pathNormalizationStrategyStack.pop();
+ if ( currentPersisterReferenceContext instanceof HierarchicalPersisterReferenceContext
) {
+ currentPersisterReferenceContext = ( ( HierarchicalPersisterReferenceContext )
currentPersisterReferenceContext ).getParent();
+ }
+ else {
+ currentPersisterReferenceContext = null;
+ }
+ }
+
+
+ // ResolutionContext impl
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public AliasBuilder getAliasBuilder() {
+ return aliasBuilder;
+ }
+
+ protected String buildUniqueImplicitAlias() {
+ return aliasBuilder.buildUniqueImplicitAlias();
+ }
+
+ public SessionFactoryImplementor getSessionFactoryImplementor() {
+ return sessionFactory;
+ }
+
+ public PersisterReferenceBuilder getPersisterReferenceBuilder() {
+ return persisterReferenceBuilder;
+ }
+
+
+ // handle trace logging
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void traceIn(String ruleName, AST tree) {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = StringHelper.repeat( '-', (traceDepth++ * 2) ) + "->
";
+ String traceText = ruleName + " (" + buildTraceNodeName(tree) +
")";
+ trace( prefix + traceText );
+ }
+
+ private String buildTraceNodeName(AST tree) {
+ return tree == null
+ ? "???"
+ : tree.getText() + " [" + printer.getTokenTypeName( tree.getType() ) +
"]";
+ }
+
+ public void traceOut(String ruleName, AST tree) {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = "<-" + StringHelper.repeat( '-', (--traceDepth *
2) ) + " ";
+ trace( prefix + ruleName );
+ }
+
+ private void trace(String msg) {
+ System.out.println( msg );
+// log.trace( msg );
+ }
+
+
+ // AST output methods
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void dumpAst(AST ast) {
+ dumpAst( ast, "DUMP" );
+ }
+
+ public void dumpAst(AST ast, String header) {
+ log.info( printer.showAsString( ast, header ) );
+ }
+
+ public void showAst(AST ast, PrintStream out) {
+ showAst( ast, new PrintWriter( out ) );
+ }
+
+ private void showAst(AST ast, PrintWriter pw) {
+ printer.showAst( ast, pw );
+ }
+
+
+ private String textOrNull(AST ast) {
+ return ast == null ? null : ast.getText();
+ }
+
+
+ // function processing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private boolean processingFunction;
+
+ protected void startingFunction() {
+ processingFunction = true;
+ }
+
+ protected void endingFunction() {
+ processingFunction = false;
+ }
+
+ public boolean isCurrentlyProcessingFunction() {
+ return processingFunction;
+ }
+
+
+ // persister-related semntic action overrides
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected AST normalizeEntityName(AST node) throws SemanticException {
+ String entityName = node.getText();
+ if ( !isEntityName( entityName ) ) {
+ final String importedName = getSessionFactoryImplementor().getImportedClassName(
entityName );
+ if ( !isEntityName( importedName ) ) {
+ throw new NoSuchEntityNameException( node );
+ }
+ node.setText( importedName );
+ }
+ return node;
+ }
+
+ private boolean isEntityName(String name) {
+ try {
+ return getSessionFactoryImplementor().getEntityPersister( name ) != null;
+ }
+ catch ( MappingException me ) {
+ return false;
+ }
+ }
+
+ protected void registerPersisterReference(AST reference) {
+ getCurrentPersisterReferenceContext().registerPersisterReference( ( PersisterReference
) reference );
+ }
+
+ protected boolean isPersisterReferenceAlias(AST alias) {
+ log.trace( "Checking [" + textOrNull( alias ) + "] as persister-ref
alias" );
+ return getCurrentPersisterReferenceContext().isContainedAlias( alias.getText() );
+ }
+
+ protected boolean isCollectionPersisterReferenceAlias(AST alias) {
+ return getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias(
alias.getText() ).isCollection();
+ }
+
+
+ // property-related semntic action overrides
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected String locateOwningPersisterAlias(AST property) {
+ PersisterReference persisterReference = getCurrentPersisterReferenceContext()
+ .locatePersisterReferenceExposingProperty( property.getText() );
+ return persisterReference == null ? null : persisterReference.getAlias();
+ }
+
+
+ // path normalization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected AST normalizeQualifiedRoot(AST alias) {
+ log.debug( "normalizing path expression root as alias [" + alias.getText() +
"]" );
+ return pathNormalizationStrategyStack.getCurrent().handleRoot(
getCurrentPersisterReferenceContext().locatePersisterReferenceByAlias( alias.getText() )
);
+ }
+
+ protected AST normalizeUnqualifiedRoot(AST propertyName) {
+ log.debug( "normalizing path expression root as unqualified property [" +
propertyName.getText() + "]" );
+ PathedPropertyReferenceSource root =
pathNormalizationStrategyStack.getCurrent().handleRoot(
getCurrentPersisterReferenceContext().locatePersisterReferenceExposingProperty(
propertyName.getText() ) );
+ return root.handleIntermediatePathPart( ( Ident ) propertyName );
+ }
+
+ protected AST normalizePropertyPathIntermediary(AST source, AST propertyNameNode) {
+ log.trace( "normalizing intermediate path expression [" + textOrNull(
propertyNameNode ) + "]" );
+ return pathNormalizationStrategyStack.getCurrent().handleIntermediatePathPart( (
PathedPropertyReferenceSource ) source, ( Ident ) propertyNameNode );
+ }
+
+ protected AST normalizePropertyPathTerminus(AST source, AST propertyNameNode) {
+ log.trace( "normalizing terminal path expression [" + textOrNull(
propertyNameNode ) + "]" );
+ return pathNormalizationStrategyStack.getCurrent().handleTerminalPathPart( (
PathedPropertyReferenceSource ) source, ( Ident ) propertyNameNode );
+ }
+
+
+ // property path normalization strategies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void pushFromClausePropertyPathContext(AST joinTypeNode, AST fetch, AST alias,
AST propertyFetch) {
+ pathNormalizationStrategyStack.push(
+ new FromClausePathNormalizationStrategy(
+ this,
+ resolveJoinType( joinTypeNode ),
+ fetch != null,
+ propertyFetch != null,
+ textOrNull( alias )
+ )
+ );
+ }
+
+ private JoinType resolveJoinType(AST joinType) {
+ int joinTypeType = joinType == null ? INNER : joinType.getType();
+ switch ( joinTypeType ) {
+ case INNER:
+ return JoinType.INNER;
+ case LEFT:
+ return JoinType.LEFT;
+ case RIGHT:
+ return JoinType.RIGHT;
+ case FULL:
+ return JoinType.FULL;
+ }
+ // if no match found, throw exception
+ throw new QueryException( "Unrecognized join type [" + joinType.getText() +
"]" );
+ }
+
+ protected void popFromClausePropertyPathContext() {
+ popPathNormalizationContext();
+ }
+
+ private void popPathNormalizationContext() {
+ pathNormalizationStrategyStack.pop();
+ }
+
+ protected void pushSelectClausePropertyPathContext() {
+ pathNormalizationStrategyStack.push( new SelectClausePathNormalizationStrategy( this )
);
+ }
+
+ protected void popSelectClausePropertyPathContext() {
+ popPathNormalizationContext();
+ }
+
+ protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+ pathNormalizationStrategyStack.push(
+ new OnFragmentPathNormalizationStrategy( this, ( PersisterReference )
rhsPersisterReference )
+ );
+ }
+
+ protected void popOnFragmentPropertyPathContext() {
+ popPathNormalizationContext();
+ }
+
+ protected void pushWithFragmentPropertyPathContext(AST rhsPropertyReference) {
+ PropertyReference propertyReference = ( PropertyReference ) rhsPropertyReference;
+ PersisterReference lhs = propertyReference.getSource().locatePersisterReference();
+// PersisterReference rhs = null;
+// pathNormalizationStrategyStack.push(
+// new WithFragmentPathNormalizationStrategy( this, lhs, rhs )
+// );
+ pathNormalizationStrategyStack.push( new WithFragmentPathNormalizationStrategy( this,
lhs ) );
+ }
+
+ protected void popWithFragmentPropertyPathContext() {
+ super.popWithFragmentPropertyPathContext();
+ }
+
+ protected void applyWithFragment(AST withFragment) {
+ ( ( WithFragmentPathNormalizationStrategy ) pathNormalizationStrategyStack.getCurrent()
).applyWithFragment( withFragment );
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Ident.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,35 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * Represents an {@link HqlNormalizeTokenTypes#IDENT} node. Defined as a separate Node
class mostly to allow for
+ * typesafety in argument passing.
+ *
+ * @author Steve Ebersole
+ */
+public class Ident extends Node {
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/InsertStatement.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing <tt>INSERT</tt> statements
+ *
+ * @author Steve Ebersole
+ */
+public class InsertStatement extends Node implements Statement {
+ public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext
normalizationContext) {
+ return new BasicPathNormalizationStrategySupport( normalizationContext ) {
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException(
+ "insert statement cannot contain implicit join path expressions"
+ );
+ }
+ };
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Join.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,58 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.JoinType;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class Join extends Node {
+ private boolean forced = false;
+
+ public void force() {
+ forced = true;
+ }
+
+ public boolean isForced() {
+ return forced;
+ }
+
+ public Node getJoinType() {
+ return ( Node ) getFirstChild();
+ }
+
+ public JoinType getEnumeratedJoinType() {
+ return JoinType.resolve( getJoinType() );
+ }
+
+ public PersisterReference getRhs() {
+ return ( PersisterReference ) getFirstChild().getNextSibling();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NoSuchEntityNameException.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.DetailedSemanticException;
+
+/**
+ * Thrown to indicate that a specified entity name could not be resolved.
+ *
+ * @author Steve Ebersole
+ */
+public class NoSuchEntityNameException extends DetailedSemanticException {
+ private final String entityName;
+
+ public NoSuchEntityNameException(AST entityNameNode) {
+ super( "Unable to resolve entity name [" + entityNameNode.getText() +
"]", entityNameNode );
+ this.entityName = entityNameNode.getText();
+ }
+
+ public String getEntityName() {
+ return entityName;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContext.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,87 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.ASTFactory;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.sql.ast.util.ASTPrinter;
+
+/**
+ * Defines the environment or context in which normalization is occuring, more
specifically
+ * defining the capabilities available in said context.
+*
+* @author Steve Ebersole
+*/
+public interface NormalizationContext {
+ /**
+ * The factory for creating AST nodes in this context.
+ *
+ * @return The AST node factory.
+ */
+ public ASTFactory getASTFactory();
+
+ /**
+ * The session factory available for this context. Providing, for example, mapping
information.
+ *
+ * @return The session factory.
+ */
+ public SessionFactoryImplementor getSessionFactoryImplementor();
+
+ /**
+ * The alias builder available in this context.
+ *
+ * @return The alias builder.
+ */
+ public AliasBuilder getAliasBuilder();
+
+ /**
+ * The current {@link PersisterReferenceContext} for this context. The {@link
PersisterReferenceContext}
+ * can change in relation to subqueries and such. See {@link PersisterReferenceContext}
docs for more info.
+ *
+ * @return The current {@link PersisterReferenceContext} for this normalization
context.
+ */
+ public PersisterReferenceContext getCurrentPersisterReferenceContext();
+
+ /**
+ * The builder of {@link PersisterReference} instances for this context.
+ *
+ * @return The {@link PersisterReference} builder.
+ */
+ public PersisterReferenceBuilder getPersisterReferenceBuilder();
+
+ /**
+ * The AST printer available for this context.
+ *
+ * @return The AST printer.
+ */
+ public ASTPrinter getPrinter();
+
+ /**
+ * Is this context currently processing a function?
+ *
+ * @return True or false.
+ */
+ public boolean isCurrentlyProcessingFunction();
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizationContextAwareNode.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * Injection contract for {@link org.hibernate.sql.ast.common.Node nodes} needing access
to the
+ * {@link NormalizationContext}.
+ *
+ * @author Steve Ebersole
+ */
+public interface NormalizationContextAwareNode {
+ /**
+ * {@link NormalizationContext} injection service.
+ *
+ * @param resolutionContext The resolution context.
+ */
+ public void injectResolutionContext(NormalizationContext resolutionContext);
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterAliasReference.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,53 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.type.Type;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterAliasReference extends Node implements PropertyReferenceSource,
NormalizationContextAwareNode {
+ private NormalizationContext resolutionContext;
+
+ public String getPersisterAlias() {
+ return getText();
+ }
+
+ public PersisterReference locatePersisterReference() {
+ return resolutionContext.getCurrentPersisterReferenceContext()
+ .locatePersisterReferenceByAlias( getPersisterAlias() );
+ }
+
+ public void injectResolutionContext(NormalizationContext resolutionContext) {
+ this.resolutionContext = resolutionContext;
+ }
+
+ public Type getPropertyType(String property) {
+ return locatePersisterReference().getPropertyType( property );
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReference.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,96 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+
+/**
+ * Contract for persister references.
+ *
+ * @author Steve Ebersole
+ */
+public interface PersisterReference extends AST, PropertyReferenceSource {
+ /**
+ * Get the alias assigned to this persister reference. May be explcitly defined by the
query author or
+ * supplied by {@link AliasBuilder#buildUniqueImplicitAlias()}, but all persister
references will have an alias.
+ *
+ * @return This persister reference's alias.
+ */
+ public String getAlias();
+
+ /**
+ * Get the name of this persister reference.
+ * @return The name.
+ */
+ public String getName();
+
+ /**
+ * Is this persister reference representing a collection persister?
+ *
+ * @return True/false.
+ */
+ public boolean isCollection();
+
+ /**
+ * Get the type mapping of the underlying persister,
+ *
+ * @return The unerlygin persister's type mapping.
+ */
+ public AssociationType getPersisterType();
+
+ /**
+ * Get the type mapping of a property originating from this persister reference.
+ *
+ * @param propertyName The property name.
+ * @return The type mapping.
+ */
+ public Type getPropertyType(String propertyName);
+
+ /**
+ * Does this persister reference represent a persister which contains a property of the
given name?
+ *
+ * @param propertyName The property name.
+ * @return True/false.
+ */
+ public boolean containsProperty(String propertyName);
+
+ /**
+ * Locate a reusable property join originating from this persister reference.
+ *
+ * @param path The property path.
+ * @return The reusable join, or null if none yet {@link #registerReusablePropertyJoin
registered}.
+ */
+ public Join locateReusablePropertyJoin(String path);
+
+ /**
+ * Register a reusable property join.
+ *
+ * @param path The property path
+ * @param join The join to be registered.
+ */
+ public void registerReusablePropertyJoin(String path, Join join);
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceBuilder.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,162 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import antlr.collections.AST;
+import antlr.ASTFactory;
+
+/**
+ * Centralization of code needed to build a {@link PersisterReference}
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterReferenceBuilder implements HqlNormalizeTokenTypes {
+ public static final Log log = LogFactory.getLog( PersisterReferenceBuilder.class );
+
+ private final NormalizationContext normalizationContext;
+
+ public PersisterReferenceBuilder(NormalizationContext normalizationContext) {
+ this.normalizationContext = normalizationContext;
+ }
+
+ private ASTFactory astFactory() {
+ return normalizationContext.getASTFactory();
+ }
+
+ private PersisterReferenceContext persisterReferenceContext() {
+ return normalizationContext.getCurrentPersisterReferenceContext();
+ }
+
+ private AliasBuilder aliasBuilder() {
+ return normalizationContext.getAliasBuilder();
+ }
+
+ private SessionFactoryImplementor sessionFactory() {
+ return normalizationContext.getSessionFactoryImplementor();
+ }
+
+ // exposed services ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Builds an entity persister reference
+ *
+ * @param entityName The entity name to which to build a PersisterReference.
+ * @param alias The alias (or null) to apply to the built PersisterReference.
+ * @param propertyFetching Whether lazy property fetching should be enabled.
+ * @return The built PersisterReference
+ */
+ public EntityPersisterReference buildEntityPersisterReference(
+ String entityName,
+ String alias,
+ boolean propertyFetching) {
+ EntityPersister persister = lookupEntityPersister( entityName );
+ String aliasText = determineAlias( alias );
+
+ AST entityNameNode = astFactory().create( ENTITY_NAME, persister.getEntityName() );
+ AST aliasNode = astFactory().create( ALIAS, aliasText );
+ AST persisterReference = astFactory().create( ENTITY_PERSISTER_REF );
+ persisterReference.setFirstChild( entityNameNode );
+ persisterReference.addChild( aliasNode );
+ if ( propertyFetching ) {
+ persisterReference.addChild( astFactory().create( PROP_FETCH ) );
+ }
+
+ EntityPersisterReference entityPersisterReference = ( EntityPersisterReference )
persisterReference;
+ persisterReferenceContext().registerPersisterReference( entityPersisterReference );
+ return entityPersisterReference;
+ }
+
+ /**
+ * Builds a collection persister reference
+ *
+ * @param collectionRole The {@link
org.hibernate.persister.collection.CollectionPersister#getRole() collection role}
+ * for which to build a PersisterReference.
+ * @param alias The alias (or null) to apply to the built PersisterReference.
+ * @param propertyFetching Whether lazy property fetching should be enabled.
+ * @return The built PersisterReference
+ */
+ public CollectionPersisterReference buildCollectionPersisterReference(
+ String collectionRole,
+ String alias,
+ boolean propertyFetching) {
+ // todo : is this the structure we want here?
+ String aliasText = determineAlias( alias );
+
+ AST collectionRoleNode = astFactory().create( COLLECTION_ROLE, collectionRole );
+ AST aliasNode = astFactory().create( ALIAS, aliasText );
+ AST persisterReference = astFactory().create( COLLECTION_PERSISTER_REF );
+ persisterReference.setFirstChild( collectionRoleNode );
+ persisterReference.addChild( aliasNode );
+ if ( propertyFetching ) {
+ persisterReference.addChild( astFactory().create( PROP_FETCH ) );
+ }
+
+
+ CollectionPersisterReference collectionPersisterReference = (
CollectionPersisterReference ) persisterReference;
+ persisterReferenceContext().registerPersisterReference( collectionPersisterReference
);
+ return collectionPersisterReference;
+ }
+
+ private EntityPersister lookupEntityPersister(String name) {
+ // NOTE : the parser should have already normalized the entity name...
+ try {
+ // First, try to get the persister using the class name directly.
+ return sessionFactory().getEntityPersister( name );
+ }
+ catch ( MappingException ignore ) {
+ // unable to locate it using this name
+ }
+
+ // If that didn't work, try using the 'import' name.
+ String importedClassName = sessionFactory().getImportedClassName( name );
+ if ( importedClassName == null ) {
+ return null;
+ }
+ return sessionFactory().getEntityPersister( importedClassName );
+ }
+
+ private String determineAlias(String alias) {
+ if ( alias == null ) {
+ return aliasBuilder().buildUniqueImplicitAlias();
+ }
+ else {
+ if ( persisterReferenceContext().isContainedAlias( alias ) ) {
+ throw new DuplicateAliasException( alias );
+ }
+ return alias;
+ }
+ }
+
+ public static boolean isImplicitAlias(String alias) {
+ return AliasBuilder.isImplicitAlias( alias );
+ }
+
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PersisterReferenceContext.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,81 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface PersisterReferenceContext {
+ /**
+ * Does the given text represent an alias for a persister within this context?
+ *
+ * @param text The potential persister alias.
+ * @return True if given text is a persister alias; false otherwise.
+ */
+ public boolean isContainedAlias(String text);
+
+ /**
+ * Does the given text represent a property exposed from a persister in this context?
+ *
+ * @param propertyName The potential property name.
+ * @return True if a persister in this context exposes such a property; false
otherwise.
+ */
+ public boolean isContainedExposedProperty(String propertyName);
+
+ /**
+ * ???
+ * todo : needed?
+ *
+ * @param aliasOrPropertyName
+ * @return
+ */
+ public PersisterReference locatePersisterReference(String aliasOrPropertyName);
+
+ /**
+ * Locate a {@link PersisterReference} by alias.
+ *
+ * @param alias The alias by which to locate the persister reference.
+ * @return The persister reference, or null.
+ */
+ public PersisterReference locatePersisterReferenceByAlias(String alias);
+
+ /**
+ * Locate an persister reference in this context which exposes the
+ * specified property.
+ *
+ * @param propertyName The name of the property.
+ * @return The persister reference, or null.
+ */
+ public PersisterReference locatePersisterReferenceExposingProperty(String
propertyName);
+
+ /**
+ * Registers a persister reference in this context.
+ *
+ * @param persisterReference The persister reference to register.
+ */
+ public void registerPersisterReference(PersisterReference persisterReference);
+
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReference.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,66 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.type.Type;
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyReference extends Node {
+ private String originalPath;
+
+ public String getOriginalPath() {
+ return originalPath;
+ }
+
+ public void injectOriginalPath(String originalPath) {
+ if ( originalPath == null ) {
+ this.originalPath = originalPath;
+ }
+ }
+
+ public PropertyReferenceSource getSource() {
+ return ( PropertyReferenceSource ) getFirstChild();
+ }
+
+ public Node getPropertyNameNode() {
+ return ( Node ) getFirstChild().getNextSibling();
+ }
+
+ public String getPropertyName() {
+ return getPropertyNameNode().getText();
+ }
+
+ public Type getMappingType() {
+ return getSource().getPropertyType( getPropertyName() );
+ }
+
+ public String getNormalizedPath() {
+ return getFirstChild().getText() + '.' + getPropertyName();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/PropertyReferenceSource.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.type.Type;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public interface PropertyReferenceSource extends AST {
+ public PersisterReference locatePersisterReference();
+ public Type getPropertyType(String property);
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/QuerySpec.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,41 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class QuerySpec extends Node {
+ public Node locateFromClause() {
+ return ( Node ) getFirstChild().getFirstChild();
+ }
+
+ public Node locateSelectClause() {
+ return ( Node ) locateFromClause().getNextSibling();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/RootPersisterReferenceContext.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,116 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.QueryException;
+
+/**
+ * Defines the contract for implementors of a "context" or a "scope"
for references to persisters. Generally speaking,
+ * this maps to the notion of a FROM clause in a SELECT statement. However, DML
operations also have a notion of a
+ * persister reference. This, then, acts as the abstraction of these grouped references
to persisters.
+ *
+ * @see PersisterReference
+ *
+ * @author Steve Ebersole
+ */
+public class RootPersisterReferenceContext implements PersisterReferenceContext {
+ private static final Logger log = LoggerFactory.getLogger(
RootPersisterReferenceContext.class );
+
+ private List persisterReferences = new ArrayList();
+ private Map aliasXref = new HashMap();
+
+ /**
+ * {@inheritDoc}
+ */
+ public void registerPersisterReference(PersisterReference persisterReference) {
+ if ( persisterReference.getAlias() == null ) {
+ throw new IllegalArgumentException( "unexpected null persister-reference
alias" );
+ }
+ persisterReferences.add( persisterReference );
+ aliasXref.put( persisterReference.getAlias(), persisterReference );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isContainedAlias(String alias) {
+ return aliasXref.containsKey( alias );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isContainedExposedProperty(String propertyName) {
+ // a matching alias always takes precedence...
+ return ( ! isContainedAlias( propertyName ) ) &&
locatePersisterReferenceExposingProperty( propertyName ) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersisterReference locatePersisterReference(String aliasOrPropertyName) {
+ PersisterReference persisterReference = locatePersisterReferenceByAlias(
aliasOrPropertyName );
+ if ( persisterReference == null ) {
+ persisterReference = locatePersisterReferenceExposingProperty( aliasOrPropertyName );
+ }
+ return persisterReference;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersisterReference locatePersisterReferenceByAlias(String alias) {
+ log.trace( "attempting to resolve [" + alias + "] as persister reference
alias" );
+ return ( PersisterReference ) aliasXref.get( alias );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PersisterReference locatePersisterReferenceExposingProperty(String propertyName)
{
+ log.trace( "attempting to resolve [" + propertyName + "] as unqualified
property" );
+ PersisterReference persisterReference = null;
+ Iterator itr = persisterReferences.iterator();
+ while( itr.hasNext() ) {
+ final PersisterReference test = ( PersisterReference ) itr.next();
+ if ( test.containsProperty( propertyName ) ) {
+ if ( persisterReference != null ) {
+ // todo : better exception type
+ throw new QueryException( "multiple persisters contained property [" +
propertyName + "]" );
+ }
+ persisterReference = test;
+ }
+ }
+ return persisterReference;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectItem.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class SelectItem extends Node {
+ public Node getSelectExpression() {
+ return ( Node ) getFirstChild();
+ }
+
+ public Node getAlias() {
+ return ( Node ) getFirstChild().getNextSibling();
+ }
+
+ public String getAliasText() {
+ return getAlias() == null ? null : getAlias().getText();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/SelectStatement.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,45 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class SelectStatement extends Node implements Statement {
+ public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext
normalizationContext) {
+ return new BasicPathNormalizationStrategySupport( normalizationContext );
+ }
+
+ public QuerySpec locateQuerySpec() {
+ return ( QuerySpec ) getFirstChild();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/Statement.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,38 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+
+/**
+ * Contract for HQL statements.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public interface Statement extends AST {
+ public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext
normalizationContext);
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/UpdateStatement.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import
org.hibernate.sql.ast.phase.hql.normalize.path.impl.BasicPathNormalizationStrategySupport;
+import org.hibernate.HibernateException;
+
+/**
+ * Specialized statement node for representing <tt>UPDATE</tt> statements
+ *
+ * @author Steve Ebersole
+ */
+public class UpdateStatement extends Node implements Statement {
+ public PathNormalizationStrategy getBasicPathNormalizationStrategy(NormalizationContext
normalizationContext) {
+ return new BasicPathNormalizationStrategySupport( normalizationContext ) {
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ throw new HibernateException(
+ "update statement cannot contain implicit join path expressions"
+ );
+ }
+ };
+ }
+}
\ No newline at end of file
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/AbstractPathNormalizationStrategy.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,422 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.AliasBuilder;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReferenceBuilder;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.sql.ast.phase.hql.normalize.DuplicateAliasException;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.util.DisplayableNode;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import antlr.collections.AST;
+import antlr.CommonAST;
+import antlr.Token;
+
+/**
+ * Abstract implementation of {@link PathNormalizationStrategy} providing convenience
methods to actual
+ * {@link PathNormalizationStrategy} implementors.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractPathNormalizationStrategy implements
PathNormalizationStrategy, HqlNormalizeTokenTypes {
+ private static final Logger log = LoggerFactory.getLogger(
AbstractPathNormalizationStrategy.class );
+
+ protected final NormalizationContext normalizationContext;
+ private PersisterReference root; // todo whether we need this depends on how we deciode
to structure the prop-joins...
+ private String pathThusFar = null;
+
+ protected AbstractPathNormalizationStrategy(NormalizationContext normalizationContext)
{
+ this.normalizationContext = normalizationContext;
+ }
+
+ /**
+ * Getter for property 'root'.
+ *
+ * @return Value for property 'root'.
+ */
+ protected PersisterReference getRoot() {
+ return root;
+ }
+
+
+ // normalization context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ /**
+ * Getter for property 'normalizationContext'.
+ *
+ * @return Value for property 'normalizationContext'.
+ */
+ protected NormalizationContext getNormalizationContext() {
+ return normalizationContext;
+ }
+
+ protected final AST createNode(int type, String text) {
+ return getNormalizationContext().getASTFactory().create( type, text );
+ }
+
+ /**
+ * Getter for property 'aliasBuilder'.
+ *
+ * @return Value for property 'aliasBuilder'.
+ */
+ protected final AliasBuilder getAliasBuilder() {
+ return getNormalizationContext().getAliasBuilder();
+ }
+
+ /**
+ * Getter for property 'persisterReferenceBuilder'.
+ *
+ * @return Value for property 'persisterReferenceBuilder'.
+ */
+ protected final PersisterReferenceBuilder getPersisterReferenceBuilder() {
+ return getNormalizationContext().getPersisterReferenceBuilder();
+ }
+
+ /**
+ * Getter for property 'sessionFactoryImplementor'.
+ *
+ * @return Value for property 'sessionFactoryImplementor'.
+ */
+ protected final SessionFactoryImplementor getSessionFactoryImplementor() {
+ return getNormalizationContext().getSessionFactoryImplementor();
+ }
+
+ /**
+ * Getter for property 'ASTPrinter'.
+ *
+ * @return Value for property 'ASTPrinter'.
+ */
+ protected final ASTPrinter getASTPrinter() {
+ return getNormalizationContext().getPrinter();
+ }
+
+
+ // path
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ protected void initializePathSoFar(String root) {
+ pathThusFar = root;
+ }
+
+ /**
+ * Getter for property 'pathThusFar'.
+ *
+ * @return Value for property 'pathThusFar'.
+ */
+ public String getPathThusFar() {
+ return pathThusFar;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource handleRoot(PersisterReference
persisterReference) {
+ initializePathSoFar( persisterReference.getAlias() );
+ root = persisterReference;
+ log.trace( "handling root path source [" + pathThusFar + "]" );
+ return internalHandleRoot( persisterReference );
+ }
+
+ /**
+ * Hook for subclasses to process the path root.
+ *
+ * @param persisterReference The persister defining the source root.
+ * @return The appropriate property path source implementation.
+ */
+ protected abstract PathedPropertyReferenceSource internalHandleRoot(PersisterReference
persisterReference);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PathedPropertyReferenceSource
handleIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText();
+ log.trace( "handling intermediate path source [" + pathThusFar +
"]" );
+ return internalResolveIntermediatePathPart( source, pathPart );
+ }
+
+ /**
+ * Hook for subclasses to process an intermediate part of the path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @return The appropriate property path source implementation.
+ */
+ protected PathedPropertyReferenceSource
internalResolveIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart)
{
+ return source.handleIntermediatePathPart( pathPart );
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final PropertyReference handleTerminalPathPart(PathedPropertyReferenceSource
source, Ident pathPart) {
+ pathThusFar = ( pathThusFar == null ) ? pathPart.getText() : pathThusFar +
"." + pathPart.getText();
+ log.trace( "handling terminal path part [" + pathThusFar + "]" );
+ try {
+ return internalResolveTerminalPathPart( source, pathPart );
+ }
+ finally {
+ pathThusFar = null;
+ }
+ }
+
+ /**
+ * Hook for subclasses to process the terminal (or ending) part of a path.
+ *
+ * @param source The source from which pathPart originates.
+ * @param pathPart The name of the path part to be processed.
+ * @return a {@link #PROPERTY_REF} node representing the normalized property path.
+ */
+ protected PropertyReference
internalResolveTerminalPathPart(PathedPropertyReferenceSource source, Ident pathPart) {
+ return source.handleTerminalPathPart( pathPart );
+ }
+
+ /**
+ * Convenience method to locate the index of a component sub-property. The returned
index is relative to
+ * {@link ComponentType#getPropertyNames}.
+ *
+ * @param componentType The component type mapping.
+ * @param subPropertyName The sub-property name.
+ * @return The index.
+ */
+ protected final int locateComponentPropertyIndex(ComponentType componentType, Ident
subPropertyName) {
+ return locateComponentPropertyIndex( componentType, subPropertyName.getText() );
+ }
+
+ /**
+ * Convenience method to locate the index of a component sub-property. The returned
index is relative to
+ * {@link ComponentType#getPropertyNames}.
+ *
+ * @param componentType The component type mapping.
+ * @param subPropertyName The sub-property name.
+ * @return The index.
+ */
+ protected static int locateComponentPropertyIndex(ComponentType componentType, String
subPropertyName) {
+ String[] componentPropertyNames = componentType.getPropertyNames();
+ for ( int i = 0; i < componentPropertyNames.length; i++ ) {
+ if ( componentPropertyNames[i].equals( subPropertyName ) ) {
+ return i;
+ }
+ }
+ throw new QueryException( "could not locate component property [" +
subPropertyName + "]" );
+ }
+
+ /**
+ * Generate a {@link #PROPERTY_REF} node.
+ *
+ * @param origin The persister from which the property originates.
+ * @param propertyName The name of the property being referenced.
+ * @return The {@link #PROPERTY_REF} node.
+ */
+ protected final PropertyReference generatePropertyReference(PersisterReference origin,
String propertyName) {
+ AST propertyReference = createNode( PROPERTY_REF, "property-reference" );
+ propertyReference.addChild( createNode( ALIAS_REF, origin.getAlias() ) );
+ propertyReference.addChild( createNode( IDENT, propertyName ) );
+ return ( PropertyReference ) propertyReference;
+ }
+
+ /**
+ * Locate (if property joins are reusable) or build an appropriate join.
+ *
+ * @param lhs The join lhs, which is the origin of the property.
+ * @param propertyName The name of the property
+ * @param alias The alias, if any, to apply to the generated RHS persister reference.
+ * @param propertyFetching Should property fetching be applied to the generated RHS?
+ * @param associationFetch Did this property join specify association fetching (join
fetch)?
+ * @return The appropriate join.
+ */
+ protected final Join locateOrBuildPropertyJoin(
+ PersisterReference lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetch) {
+ Join join = null;
+
+ if ( areJoinsReusable() ) {
+ join = lhs.locateReusablePropertyJoin( propertyName );
+ }
+
+ if ( join == null ) {
+ join = buildPropertyJoin( lhs, propertyName, alias, propertyFetching, associationFetch
);
+ if ( areJoinsReusable() ) {
+ lhs.registerReusablePropertyJoin( propertyName, join );
+ }
+ }
+
+ return join;
+ }
+
+ /**
+ * Build a property join node.
+ *
+ * @param lhs The join's left-hand-side persister-reference
+ * @param propertyName The property name.
+ * @param alias The alias to apply to the rhs of the join
+ * @param propertyFetching should property fetching be applied to the joined persister?
+ * @param associationFetch Should the association making up the property join also be
fetched?
+ *
+ * @return The right-hand-side persister-reference.
+ */
+ protected Join buildPropertyJoin(
+ PersisterReference lhs,
+ String propertyName,
+ String alias,
+ boolean propertyFetching,
+ boolean associationFetch) {
+ validateJoinCreation( lhs, propertyName );
+
+ PersisterReference rhs = null;
+ final Type associationType = lhs.getPropertyType( propertyName );
+ if ( associationType.isCollectionType() ) {
+ CollectionType collectionType = ( CollectionType ) associationType;
+ rhs = getPersisterReferenceBuilder().buildCollectionPersisterReference(
+ collectionType.getRole(),
+ alias,
+ propertyFetching
+ );
+ }
+ else if ( associationType.isEntityType() ) {
+ EntityType entityType = ( EntityType ) associationType;
+ String entityName = entityType.getAssociatedEntityName( getSessionFactoryImplementor()
);
+ rhs = getPersisterReferenceBuilder().buildEntityPersisterReference( entityName, alias,
propertyFetching );
+ }
+ else {
+ throw new HibernateException( "cannot create join on non-association [name="
+ propertyName + ", type=" + associationType + "]" );
+ }
+
+ Join propertyJoinNode = ( Join ) createNode( JOIN, "join" );
+ propertyJoinNode.setFirstChild( buildJoinTypeNode() );
+ propertyJoinNode.addChild( rhs );
+
+ // todo : handle mapped join conditions, adding them to the tree
+
+ if ( associationFetch ) {
+ registerAssociationFetch( propertyJoinNode );
+ }
+
+ if ( log.isTraceEnabled() ) {
+ log.trace(
+ getASTPrinter().showAsString(
+ propertyJoinNode,
+ "implicit join [" + lhs.getAlias() + "." + propertyName +
"]"
+ )
+ );
+ }
+
+ lhs.addChild( propertyJoinNode );
+
+ return propertyJoinNode;
+ }
+
+ /**
+ * Hook to allow subclasses to disallow implicit join.
+ *
+ * @param origin The persister-reference which is the origin of the property
+ * @param property The property resulting in a join.
+ */
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ log.debug( "creating path expression implied join [" + origin.getAlias() +
"].[" + property + "]" );
+ }
+
+ private void registerAssociationFetch(Join propertyJoinNode) {
+ // todo : implement
+ }
+
+ /**
+ * Hook to allow subclasses to define the type of join to use for an implciit join.
+ * <p/>
+ * The default is to use an {@link #INNER} join.
+ *
+ * @return The join type node.
+ */
+ protected AST buildJoinTypeNode() {
+ return createNode( INNER, "inner" );
+ }
+
+ /**
+ * Does this strategy allows property joins to be reused?
+ *
+ * @return True/false.
+ */
+ protected boolean areJoinsReusable() {
+ return true;
+ }
+
+
+ // source impl support
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public abstract class AbstractPathedPropertyReferenceSource extends CommonAST
+ implements PathedPropertyReferenceSource, DisplayableNode {
+ private final String originationPath;
+
+ /**
+ * Constructs a new AbstractPathedPropertyReferenceSource.
+ */
+ protected AbstractPathedPropertyReferenceSource() {
+ this( getPathThusFar() );
+ }
+
+ protected AbstractPathedPropertyReferenceSource(Token token) {
+ this( token, getPathThusFar() );
+ }
+
+ protected AbstractPathedPropertyReferenceSource(String originationPath) {
+ this.originationPath = originationPath;
+ }
+
+ protected AbstractPathedPropertyReferenceSource(Token token, String originationPath) {
+ super( token );
+ this.originationPath = originationPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getOriginationPath() {
+ return originationPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final String getDisplayText() {
+ return " ADPATER : SHOULD NEVER END UP IN TREE!";
+ }
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategy.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,65 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+
+/**
+ * Applies a strategy pattern to the manner in which path expressions are normalized,
allowing contextual pluggability
+ * of the implicit-join handling rules...
+ *
+ * @author Steve Ebersole
+ */
+public interface PathNormalizationStrategy {
+ /**
+ * Handle the root of the pathed property reference path.
+ *
+ * @param persisterReference The root of the path.
+ *
+ * @return The source representation of the path root.
+ */
+ public PathedPropertyReferenceSource handleRoot(PersisterReference persisterReference);
+
+ /**
+ * Handle an intermeidary path part.
+ *
+ * @param source The source of the property reference.
+ * @param pathPart The current property path part.
+ *
+ * @return The new source for further property part handling.
+ */
+ public PathedPropertyReferenceSource
handleIntermediatePathPart(PathedPropertyReferenceSource source, Ident pathPart);
+
+ /**
+ * Handle the terminal path part.
+ *
+ * @param source The source of the property reference.
+ * @param pathPart The current (and terminal/last) path part.
+ *
+ * @return The terminal property reference indicated by the overall path.
+ */
+ public PropertyReference handleTerminalPathPart(PathedPropertyReferenceSource source,
Ident pathPart);
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathNormalizationStrategyStack.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,47 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import java.util.LinkedList;
+
+/**
+ * Provides a stack of {@link PathNormalizationStrategy}s
+ *
+ * @author Steve Ebersole
+ */
+public class PathNormalizationStrategyStack {
+ private LinkedList stack = new LinkedList();
+
+ public void push(PathNormalizationStrategy handler) {
+ stack.addFirst( handler );
+ }
+
+ public PathNormalizationStrategy pop() {
+ return ( PathNormalizationStrategy ) stack.removeFirst();
+ }
+
+ public PathNormalizationStrategy getCurrent() {
+ return ( PathNormalizationStrategy ) stack.getFirst();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/PathedPropertyReferenceSource.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,64 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+
+/**
+ * The contract for representing the non-terminal parts of a property path expression
+ * <p/>
+ * NOTE : extends AST so the grammar can more easily handle it, not because it will
actually end up in the syntax
+ * tree (it will not).
+ *
+ * @author Steve Ebersole
+ */
+public interface PathedPropertyReferenceSource extends AST {
+ /**
+ * Return the path which led to this source.
+ *
+ * @return The origination path.
+ */
+ public String getOriginationPath();
+
+ /**
+ * Handle an intermediate path part reference.
+ *
+ * @param name The name for the path part to handle.
+ *
+ * @return An appropriate source representation of said intermeidate path part.
+ */
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name);
+
+ /**
+ * Handle the terminal path reference.
+ *
+ * @param name The name of the terminal path part.
+ *
+ * @return The property reference.
+ */
+ public PropertyReference handleTerminalPathPart(Ident name);
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/BasicPathNormalizationStrategySupport.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,255 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.sql.ast.phase.hql.normalize.path.AbstractPathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.type.Type;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.EntityType;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.HibernateException;
+import org.hibernate.hql.CollectionProperties;
+
+/**
+ * Basic {@link
org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy}. Mainly used as
the
+ * basis for other implementations.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicPathNormalizationStrategySupport extends
AbstractPathNormalizationStrategy {
+ private static final Logger log = LoggerFactory.getLogger(
BasicPathNormalizationStrategySupport.class );
+
+ public BasicPathNormalizationStrategySupport(NormalizationContext normalizationContext)
{
+ super( normalizationContext );
+ }
+
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterReference
persisterReference) {
+ return new RootSourceImpl( persisterReference );
+ }
+
+ private PathedPropertyReferenceSource
determineAppropriateIntermediateSourceType(PersisterReference origin, Ident propertyName)
{
+ final String propertyNameText = propertyName.getText();
+ final Type propertyType = origin.getPropertyType( propertyNameText );
+ if ( propertyType.isComponentType() ) {
+ return new ComponentIntermediatePathSource( origin, propertyNameText, ( ComponentType
) propertyType );
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityIntermediatePathSource( origin, propertyNameText );
+ }
+ else if ( propertyType.isCollectionType() ) {
+ return new CollectionIntermediatePathSource( origin, propertyNameText );
+ }
+ else {
+ return new SimpleIntermediatePathSource();
+ }
+ }
+
+ /**
+ * Is the given property name a reference to the primary key of the associated
+ * entity construed by the given entity type?
+ * <p/>
+ * For example, consider a fragment like order.customer.id
+ * (where order is a from-element alias). Here, we'd have:
+ * propertyName = "id" AND
+ * owningType = ManyToOneType(Customer)
+ * and are being asked to determine whether "customer.id" is a reference
+ * to customer's PK...
+ *
+ * @param propertyName The name of the property to check.
+ * @param owningType The type represeting the entity "owning" the property
+ * @return True if propertyName references the enti ty's
(owningType->associatedEntity)
+ * primary key; false otherwise.
+ */
+ private boolean isReferenceToPrimaryKey(EntityType owningType, String propertyName) {
+ EntityPersister persister = getSessionFactoryImplementor().getEntityPersister(
+ owningType.getAssociatedEntityName( getSessionFactoryImplementor() )
+ );
+ if ( persister.getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
+ // only the identifier property field name can be a reference to the associated
entity's PK...
+ return propertyName.equals( persister.getIdentifierPropertyName() ) &&
owningType.isReferenceToPrimaryKey();
+ }
+ else {
+ // here, we have two possibilities:
+ // 1) the property-name matches the explicitly identifier property name
+ // 2) the property-name matches the implicit 'id' property name
+ if ( EntityPersister.ENTITY_ID.equals( propertyName ) ) {
+ // the referenced node text is the special 'id'
+ return owningType.isReferenceToPrimaryKey();
+ }
+ else {
+ String keyPropertyName = owningType.getIdentifierOrUniqueKeyPropertyName(
getSessionFactoryImplementor() );
+ return keyPropertyName != null && keyPropertyName.equals( propertyName )
&& owningType.isReferenceToPrimaryKey();
+ }
+ }
+ }
+
+
+
+ // source impls
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private class RootSourceImpl extends AbstractPathedPropertyReferenceSource {
+ private final PersisterReference lhs;
+
+ public RootSourceImpl(PersisterReference lhs) {
+ this.lhs = lhs;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ return determineAppropriateIntermediateSourceType( lhs, name );
+ }
+
+ public PropertyReference handleTerminalPathPart(Ident name) {
+ final String nameText = name.getText();
+ if ( lhs.getPropertyType( nameText ).isEntityType() ) {
+ if ( shouldTerminalEntityPropertyForceJoin() ) {
+ locateOrBuildPropertyJoin( lhs, nameText, null, false, false );
+ }
+ }
+ return generatePropertyReference( lhs, name.getText() );
+ }
+
+ public String getText() {
+ return "root-source {" + lhs.getAlias() + "}";
+ }
+ }
+
+ protected class SimpleIntermediatePathSource extends
AbstractPathedPropertyReferenceSource {
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ throw new HibernateException( "cannot dereference simple value as part of path
expression" );
+ }
+
+ public PropertyReference handleTerminalPathPart(Ident name) {
+ throw new HibernateException( "cannot dereference simple value as part of path
expression" );
+ }
+ }
+
+ private class ComponentIntermediatePathSource extends
AbstractPathedPropertyReferenceSource {
+ private final PersisterReference lhs;
+ private final String propertyPath;
+ private final ComponentType componentType;
+
+ public ComponentIntermediatePathSource(PersisterReference lhs, String propertyPath) {
+ this( lhs, propertyPath, ( ComponentType ) lhs.getPropertyType( propertyPath ) );
+ }
+
+ private ComponentIntermediatePathSource(PersisterReference lhs, String propertyPath,
ComponentType componentType) {
+ this.lhs = lhs;
+ this.propertyPath = propertyPath;
+ this.componentType = componentType;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ final String propertyName = name.getText();
+ final int index = locateComponentPropertyIndex( componentType, propertyName );
+ final String path = buildComponentDereferencePath( propertyName );
+ final Type propertyType = componentType.getSubtypes()[index];
+ if ( propertyType.isComponentType() ) {
+ return new ComponentIntermediatePathSource( lhs, path, ( ComponentType ) propertyType
);
+ }
+ else if ( propertyType.isEntityType() ) {
+ return new EntityIntermediatePathSource( lhs, path );
+ }
+ else {
+ return new SimpleIntermediatePathSource();
+ }
+ }
+
+ public PropertyReference handleTerminalPathPart(Ident name) {
+ return generatePropertyReference( lhs, buildComponentDereferencePath( name.getText() )
);
+ }
+
+ private String buildComponentDereferencePath(String subPropertyName) {
+ return propertyPath + "." + subPropertyName;
+ }
+ }
+
+ protected class EntityIntermediatePathSource extends
AbstractPathedPropertyReferenceSource {
+ private final PersisterReference lhs;
+ private final String lhsPropertyName;
+
+ public EntityIntermediatePathSource(PersisterReference lhs, String lhsPropertyName) {
+ this.lhs = lhs;
+ this.lhsPropertyName = lhsPropertyName;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ Join join = locateOrBuildPropertyJoin( lhs, lhsPropertyName, null, false, false );
+ return determineAppropriateIntermediateSourceType( join.getRhs(), name );
+ }
+
+ public PropertyReference handleTerminalPathPart(Ident name) {
+ final EntityType type = ( EntityType ) lhs.getPropertyType( lhsPropertyName );
+ if ( isReferenceToPrimaryKey( type, lhsPropertyName ) ) {
+ return generatePropertyReference( lhs, lhsPropertyName + "." +
name.getText() );
+ }
+ else {
+ Join join = locateOrBuildPropertyJoin( lhs, lhsPropertyName, null, false, false );
+ final String propertyName = name.getText();
+ if ( type.isEntityType() ) {
+ if ( shouldTerminalEntityPropertyForceJoin() ) {
+ locateOrBuildPropertyJoin( join.getRhs(), propertyName, null, false, false );
+ }
+ }
+ return generatePropertyReference( join.getRhs(), propertyName );
+ }
+ }
+ }
+
+ protected boolean shouldTerminalEntityPropertyForceJoin() {
+ return false;
+ }
+
+ protected class CollectionIntermediatePathSource extends
AbstractPathedPropertyReferenceSource {
+ private final PersisterReference lhs;
+ private final String propertyName;
+
+ public CollectionIntermediatePathSource(PersisterReference lhs, String propertyName) {
+ this.lhs = lhs;
+ this.propertyName = propertyName;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ throw new HibernateException( "cannot implicit join across a collection
association" );
+ }
+
+ public PropertyReference handleTerminalPathPart(Ident name) {
+ // TODO : what are the circusmstances under which we need to *join* to the collection,
as opposed to say munge it into a subquery???
+ final String nameText = name.getText();
+ if ( CollectionProperties.isAnyCollectionProperty( nameText ) ) {
+ Join join = locateOrBuildPropertyJoin( lhs, propertyName, null, false, false );
+ return generatePropertyReference( join.getRhs(), nameText );
+ }
+ throw new HibernateException( "cannot implicit join across a collection
association" );
+ }
+ }
+}
\ No newline at end of file
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/FromClausePathNormalizationStrategy.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,128 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import antlr.collections.AST;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.PropertyReference;
+import org.hibernate.sql.ast.phase.hql.normalize.Ident;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizeTokenTypes;
+import org.hibernate.sql.ast.phase.hql.normalize.path.AbstractPathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.type.Type;
+import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
+
+/**
+ *
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for
dealing with path expressions
+ * occuring in the <tt>FROM</tt> clause of a query.
+ *
+ * @author Steve Ebersole
+ */
+public class FromClausePathNormalizationStrategy extends
AbstractPathNormalizationStrategy
+ implements PathNormalizationStrategy, HqlNormalizeTokenTypes {
+
+ private final JoinType joinType;
+ private final boolean associationFetch;
+ private final boolean propertyFetch;
+ private final String alias;
+
+
+ /**
+ * Instantiate a normalization strategy for handling path expressions in a
<tt>FROM</tt> clause.
+ *
+ * @param normalizationContext The context for normalization.
+ * @param joinType The type of explicit-join specified at the root of this path
expression.
+ * @param associationFetch Was association fetching indicated on this path expression?
+ * @param propertyFetch Was property fetching indicated on this path expression?
+ * @param alias The alias (if one) specified on this joined path expression.
+ */
+ public FromClausePathNormalizationStrategy(
+ NormalizationContext normalizationContext,
+ JoinType joinType,
+ boolean associationFetch,
+ boolean propertyFetch,
+ String alias) {
+ super( normalizationContext );
+ this.joinType = joinType;
+ this.associationFetch = associationFetch;
+ this.propertyFetch = propertyFetch;
+ this.alias = alias;
+ }
+
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterReference
persisterReference) {
+ return new SourceImpl( persisterReference );
+ }
+
+ private class SourceImpl extends AbstractPathedPropertyReferenceSource {
+ private final PersisterReference lhs;
+
+ private SourceImpl(PersisterReference lhs) {
+ this.lhs = lhs;
+ }
+
+ public PathedPropertyReferenceSource handleIntermediatePathPart(Ident name) {
+ // TODO : still need to account for paths including component dereferences...
+ return new SourceImpl( locateOrBuildPropertyJoin( lhs, name.getText(), null, false,
associationFetch ).getRhs() );
+ }
+
+ public PropertyReference handleTerminalPathPart(Ident name) {
+ final String propertyName = name.getText();
+ Type terminalPropertyType = lhs.getPropertyType( propertyName );
+ if ( !terminalPropertyType.isAssociationType() ) {
+ throw new HibernateException( "non-association type cannot be used as
termination of path expression in from clause" );
+ }
+
+ locateOrBuildPropertyJoin( lhs, name.getText(), alias, propertyFetch, associationFetch
);
+
+ PropertyReference propertyReference = generatePropertyReference( lhs, name.getText()
);
+ propertyReference.injectOriginalPath( getPathThusFar() );
+
+ return propertyReference;
+ }
+ }
+
+ protected AST buildJoinTypeNode() {
+ if ( joinType == JoinType.INNER ) {
+ return createNode( INNER, "inner" );
+ }
+ else if ( joinType == JoinType.LEFT ) {
+ return createNode( LEFT, "left" );
+ }
+ else if ( joinType == JoinType.RIGHT ) {
+ return createNode( RIGHT, "right" );
+ }
+ // if no match found, throw exception
+ throw new QueryException( "Unrecognized join type [" + joinType.toString() +
"]" );
+ }
+
+ protected boolean areJoinsReusable() {
+ return false;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/OnFragmentPathNormalizationStrategy.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.path.PathedPropertyReferenceSource;
+import org.hibernate.HibernateException;
+
+/**
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for
dealing with path expressions
+ * occuring in the <tt>ON</tt> clause of a persister join.
+ *
+ * @author Steve Ebersole
+ */
+public class OnFragmentPathNormalizationStrategy extends
BasicPathNormalizationStrategySupport {
+ private final PersisterReference joinRhs;
+ private PersisterReference joinLhs;
+
+ public OnFragmentPathNormalizationStrategy(NormalizationContext resolutionContext,
PersisterReference joinRhs) {
+ super( resolutionContext );
+ this.joinRhs = joinRhs;
+ }
+
+ public PersisterReference getDiscoveredLHS() {
+ return joinLhs;
+ }
+
+ protected PathedPropertyReferenceSource internalHandleRoot(PersisterReference
persisterReference) {
+ // persisterReference must either refer to our LHS or RHS...
+ if ( persisterReference == joinRhs ) {
+ // nothing to do...
+ }
+ else if ( joinLhs != null ) {
+ if ( persisterReference != joinLhs ) {
+ throw new HibernateException(
+ "path root not resolveable against either left-hand-side [" +
+ joinLhs.getText() + "] nor right-hand-side [" +
+ joinRhs.getText() + "] of the join"
+ );
+ }
+ }
+ else {
+ joinLhs = persisterReference;
+ }
+ return super.internalHandleRoot( persisterReference );
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/SelectClausePathNormalizationStrategy.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,46 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+
+/**
+ * Essentially the same stragety as {@link BasicPathNormalizationStrategySupport} expcept
that in the select clause
+ * an entity encountered as the terminal part must force a join...
+ * <p/>
+ * todo : the above is true as long as the path is not a function argument...
+ *
+ * @author Steve Ebersole
+ */
+public class SelectClausePathNormalizationStrategy extends
BasicPathNormalizationStrategySupport {
+
+ public SelectClausePathNormalizationStrategy(NormalizationContext normalizationContext)
{
+ super( normalizationContext );
+ }
+
+ protected boolean shouldTerminalEntityPropertyForceJoin() {
+ // here we should *as long as* we are not part of a function processing
+ return ! getNormalizationContext().isCurrentlyProcessingFunction();
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/normalize/path/impl/WithFragmentPathNormalizationStrategy.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,77 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize.path.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.hibernate.sql.ast.phase.hql.normalize.PersisterReference;
+import org.hibernate.sql.ast.phase.hql.normalize.NormalizationContext;
+import org.hibernate.sql.ast.phase.hql.normalize.Join;
+import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
+
+import antlr.collections.AST;
+
+/**
+ * {@link org.hibernate.sql.ast.phase.hql.normalize.path.PathNormalizationStrategy} for
dealing with <tt>WITH</tt>
+ * fragments used to supply addition join conditions to property joins.
+ *
+ * @author Steve Ebersole
+ */
+public class WithFragmentPathNormalizationStrategy extends
BasicPathNormalizationStrategySupport {
+ public static final Log log = LogFactory.getLog(
WithFragmentPathNormalizationStrategy.class );
+
+ private final PersisterReference lhs;
+
+ public WithFragmentPathNormalizationStrategy(NormalizationContext normalizationContext,
PersisterReference lhs) {
+ super( normalizationContext );
+ this.lhs = lhs;
+ }
+
+ public void applyWithFragment(AST withFragment) {
+ PersisterReference rhs = getRoot();
+ // first, locate the actual Join node which links the lhs and rhs...
+ Join join = null;
+ AST nextPossible = lhs.getFirstChild();
+ while ( nextPossible != null ) {
+ if ( nextPossible instanceof Join ) {
+ if ( ( ( Join ) nextPossible ).getRhs() == rhs ) {
+ join = ( Join ) nextPossible;
+ break;
+ }
+ }
+ nextPossible = nextPossible.getNextSibling();
+ }
+ if ( join == null ) {
+ throw new QueryException( "could not locate specific join node to which to apply
with fragment [" + withFragment + "]" );
+ }
+ join.addChild( withFragment );
+ }
+
+ protected void validateJoinCreation(PersisterReference origin, String property) {
+ // todo : why not???
+ throw new HibernateException( "Path expression [" + origin.getText() +
"].[" + property + "] within 'with clause' cannot result in
physical join" );
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java
(from rev 15693,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/HqlParser.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/HqlParser.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,609 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.parse;
+
+import org.hibernate.sql.ast.util.ASTUtil;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.util.ErrorCounter;
+import org.hibernate.sql.ast.util.ParseErrorHandler;
+import org.hibernate.QueryException;
+import org.hibernate.MappingException;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.sql.ast.common.CommonHibernateLexer;
+import org.hibernate.sql.ast.common.TokenImpl;
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.common.NodeFactory;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.StringReader;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+import antlr.collections.AST;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+import antlr.Token;
+import antlr.ASTPair;
+import antlr.MismatchedTokenException;
+import antlr.SemanticException;
+import antlr.ASTFactory;
+
+/**
+ * The parser used by Hibernate to generate an AST given an input HQL string (a
"stream parser"). The produced
+ * AST is then used (and mutated) by later phases/parsers to apply semantic resolution;
this parser, however, is
+ * all about syntax resolution.
+ *
+ * @author Steve Ebersole
+ */
+public class HqlParser extends GeneratedHqlParser {
+ private static final Logger log = LoggerFactory.getLogger( HqlParser.class );
+
+ private final Context context;
+ private final ParseErrorHandler parseErrorHandler = new ErrorCounter();
+ private final ASTPrinter printer = new ASTPrinter( HqlParseTokenTypes.class );
+ private int traceDepth = 0;
+
+ public HqlParser(String hql, Context context) {
+ super( new CommonHibernateLexer( new StringReader( hql ) ) );
+ this.context = context;
+ super.setASTFactory( new NodeFactory() );
+ }
+
+ public HqlParser(String hql, final SessionFactoryImplementor sessionFactoryImplementor)
{
+ this( hql, wrapInContext( sessionFactoryImplementor ) );
+ }
+
+ // overrides of Antlr infastructure methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void reportError(RecognitionException e) {
+ parseErrorHandler.reportError( e );
+ }
+
+ public void reportError(String s) {
+ parseErrorHandler.reportError( s );
+ }
+
+ public void reportWarning(String s) {
+ parseErrorHandler.reportWarning( s );
+ }
+
+ public ParseErrorHandler getParseErrorHandler() {
+ return parseErrorHandler;
+ }
+
+ static public void panic() {
+ //overriden to avoid System.exit
+ throw new QueryException( "Parser: panic" );
+ }
+
+ public void setASTFactory(ASTFactory astFactory) {
+ throw new UnsupportedOperationException( "not allowed!" );
+ }
+
+
+// various AST output methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public void traceIn(String s) throws TokenStreamException {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = StringHelper.repeat( "-", (traceDepth++ * 2) ) +
"->";
+ trace( prefix + s );
+ }
+
+ public void traceOut(String s) throws TokenStreamException {
+ if ( inputState.guessing > 0 ) {
+ return;
+ }
+ String prefix = "<-" + StringHelper.repeat( "-", (--traceDepth *
2) );
+ trace( prefix + s );
+ }
+
+ private void trace(String msg) {
+ System.out.println( msg );
+// log.trace( msg );
+ }
+
+ public void dumpAst(AST ast) {
+ dumpAst( ast, "DUMP" );
+ }
+
+ public void dumpAst(AST ast, String header) {
+ log.info( printer.showAsString( ast, header ) );
+ }
+
+ public void showAst(AST ast, PrintStream out) {
+ showAst( ast, new PrintWriter( out ) );
+ }
+
+ private void showAst(AST ast, PrintWriter pw) {
+ printer.showAst( ast, pw );
+ }
+
+
+ // overrides of grammar semantic actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ public String extractPath(AST tree) {
+ try {
+ return PathCollector.getPath( tree );
+ }
+ catch ( Throwable t ) {
+ return tree.getText();
+ }
+ }
+
+ public boolean isRegisteredFunction(AST tree) {
+ return context.isRegisteredFunctionName( extractPath( tree ) );
+ }
+
+ public boolean isJavaConstant(String path) {
+ try {
+ log.debug( "Testing path [" + path + "] as potential java
constant" );
+ Object value = ReflectHelper.getConstantValueStrictly( path );
+ log.debug( "Resolved path to java constant [" + value + "]" );
+ return true;
+ }
+ catch( Throwable t ) {
+ log.debug( "Path did not resolve to java constant : " + t );
+ return false;
+ }
+ }
+
+ public String resolveEntityName(String name) {
+ return context.getImportedName( name );
+ }
+
+ public String resolveDynamicInstantiationPojoName(AST name) throws SemanticException {
+ String path = extractPath( name );
+ if ( "list".equals( path ) || "map".equals( path ) ) {
+ return path;
+ }
+ else {
+ String importedName = context.getImportedName( path );
+ try {
+ Class importedClass = ReflectHelper.classForName( importedName );
+ return importedClass.getName();
+ }
+ catch ( ClassNotFoundException e ) {
+ throw new SemanticException( "Unable to locate dynamic instantiation class
[" + importedName + "]" );
+ }
+ }
+ }
+
+ protected AST processEqualityExpression(AST x) {
+ if ( x == null ) {
+ log.warn( "processEqualityExpression() : No expression to process!" );
+ return null;
+ }
+
+ int type = x.getType();
+ if ( log.isTraceEnabled() ) {
+ log.trace( "processEqualityExpression() -> type : {}, name : {}",
Integer.toString( type ), ASTUtil.getTokenTypeName( HqlParseTokenTypes.class, type ) );
+ }
+ if ( type == EQUALS_OP || type == NOT_EQUALS_OP || type == SQL_NOT_EQUALS_OP ) {
+ boolean negated = ( type != EQUALS_OP );
+ if ( x.getNumberOfChildren() == 2 ) {
+ AST a = x.getFirstChild();
+ AST b = a.getNextSibling();
+ // (EQ NULL b) => (IS_NULL b)
+ if ( a.getType() == NULL && b.getType() != NULL ) {
+ return createIsNullParent( b, negated );
+ }
+ // (EQ a NULL) => (IS_NULL a)
+ else if ( b.getType() == NULL && a.getType() != NULL ) {
+ return createIsNullParent( a, negated );
+ }
+ else if ( b.getType() == EMPTY ) {
+ return processIsEmpty( a, negated );
+ }
+ else {
+ return x;
+ }
+ }
+ else {
+ return x;
+ }
+ }
+ else {
+ return x;
+ }
+ }
+
+ private AST createIsNullParent(AST node, boolean negated) {
+ node.setNextSibling( null );
+ int type = negated ? IS_NOT_NULL : IS_NULL;
+ String text = negated ? "is not null" : "is null";
+ return ASTUtil.createParent( astFactory, type, text, node );
+ }
+
+ protected AST processMemberOf(AST path, AST notNode) {
+ AST inNode = notNode == null ? astFactory.create( IN, "in" ) :
astFactory.create( NOT_IN, "not in" );
+ AST subqueryNode = createSubquery( path );
+ AST inListNode = ASTUtil.createParent( astFactory, IN_LIST, "in-list",
subqueryNode );
+ inNode.addChild( inListNode );
+ return inNode;
+ }
+
+ private AST createSubquery(AST subquerySource) {
+// AST ast = ASTUtil.createParent( astFactory, RANGE, "RANGE", node );
+// todo : what is the type of 'node'?
+ log.debug(
+ "Generating subquery; incoming node type = {}; incoming node = [{}]",
+ printer.getTokenTypeName( subquerySource.getType() ),
+ subquerySource
+ );
+ AST fromNode = ASTUtil.createParent( astFactory, FROM, "from", subquerySource
);
+ AST selectFromNode = ASTUtil.createParent( astFactory, SELECT_FROM,
"SELECT_FROM", fromNode );
+ return ASTUtil.createParent( astFactory, QUERY, "QUERY", selectFromNode );
+ }
+
+ protected AST processIsEmpty(AST collection, AST notToken) {
+ return processIsEmpty( collection, notToken != null );
+ }
+
+ private AST processIsEmpty(AST node, boolean negated) {
+ node.setNextSibling( null );
+ AST ast = createSubquery( node );
+ ast = ASTUtil.createParent( astFactory, EXISTS, "exists", ast );
+ // Add NOT if it's negated.
+ if ( negated ) {
+ ast = ASTUtil.createParent( astFactory, NOT, "not", ast );
+ }
+ return ast;
+ }
+ public AST negateNode(AST x) {
+ //TODO: switch statements are always evil! We already had bugs because
+ // of forgotten token types. Use polymorphism for this!
+ switch ( x.getType() ) {
+ case OR:
+ x.setType(AND);
+ x.setText("{and}");
+ negateNode( x.getFirstChild() );
+ negateNode( x.getFirstChild().getNextSibling() );
+ return x;
+ case AND:
+ x.setType(OR);
+ x.setText("{or}");
+ negateNode( x.getFirstChild() );
+ negateNode( x.getFirstChild().getNextSibling() );
+ return x;
+ case EQUALS_OP:
+ x.setType( NOT_EQUALS_OP );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (EQ a b) ) => (NE a b)
+ case NOT_EQUALS_OP:
+ x.setType( EQUALS_OP );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (NE a b) ) => (EQ a b)
+ case GREATER_THAN_OP:
+ x.setType( LESS_THAN_OR_EQUALS_OP );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (GT a b) ) => (LE a b)
+ case LESS_THAN_OP:
+ x.setType( GREATER_THAN_OR_EQUALS_OP );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (LT a b) ) => (GE a b)
+ case GREATER_THAN_OR_EQUALS_OP:
+ x.setType( LESS_THAN_OP );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (GE a b) ) => (LT a b)
+ case LESS_THAN_OR_EQUALS_OP:
+ x.setType( GREATER_THAN_OP );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (LE a b) ) => (GT a b)
+ case LIKE:
+ x.setType( NOT_LIKE );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (LIKE a b) ) => (NOT_LIKE a b)
+ case NOT_LIKE:
+ x.setType( LIKE );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (NOT_LIKE a b) ) => (LIKE a b)
+ case IN:
+ x.setType( NOT_IN );
+ x.setText( "{not}" + x.getText() );
+ return x;
+ case NOT_IN:
+ x.setType( IN );
+ x.setText( "{not}" + x.getText() );
+ return x;
+ case IS_NULL:
+ x.setType( IS_NOT_NULL );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (IS_NULL a b) ) => (IS_NOT_NULL a b)
+ case IS_NOT_NULL:
+ x.setType( IS_NULL );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (IS_NOT_NULL a b) ) => (IS_NULL a b)
+ case BETWEEN:
+ x.setType( NOT_BETWEEN );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (BETWEEN a b) ) => (NOT_BETWEEN a b)
+ case NOT_BETWEEN:
+ x.setType( BETWEEN );
+ x.setText( "{not}" + x.getText() );
+ return x; // (NOT (NOT_BETWEEN a b) ) => (BETWEEN a b)
+ case NOT:
+ return x.getFirstChild(); // (NOT (NOT x) ) => (x)
+ default:
+ return super.negateNode( x ); // Just add a 'not' parent.
+ }
+ }
+
+ protected void transferTrackingInfo(AST source, AST target) {
+ if ( target instanceof Node ) {
+ ( ( Node ) target ).transferTrackingInfo( source );
+ }
+ else {
+ super.transferTrackingInfo( source, target );
+ }
+ }
+
+ /**
+ * Overrides the base behavior to retry keywords as identifiers.
+ *
+ * @param token The token.
+ * @param ex The recognition exception.
+ * @return AST - The new AST.
+ * @throws antlr.RecognitionException if the substitution was not possible.
+ * @throws antlr.TokenStreamException if the substitution was not possible.
+ */
+ public AST handleIdentifierError(Token token, RecognitionException ex) throws
RecognitionException, TokenStreamException {
+ // If the token can tell us if it could be an identifier...
+ if ( token instanceof TokenImpl ) {
+ TokenImpl hqlToken = ( TokenImpl ) token;
+ // ... and the token could be an identifer and the error is
+ // a mismatched token error ...
+ if ( hqlToken.isPossibleIdentifier() && ex instanceof MismatchedTokenException
) {
+ MismatchedTokenException mte = ( MismatchedTokenException ) ex;
+ // ... and the expected token type was an identifier, then:
+ if ( mte.expecting == IDENT ) {
+ // Use the token as an identifier.
+ reportWarning(
+ "Keyword '"+ token.getText()
+ + "' is being interpreted as an identifier due to: "
+ + mte.getMessage()
+ );
+ // Add the token to the AST.
+ ASTPair currentAST = new ASTPair();
+// token.setType( WEIRD_IDENT );
+ token.setType( IDENT );
+ astFactory.addASTChild( currentAST, astFactory.create( token ) );
+ consume();
+ return currentAST.root;
+ }
+ }
+ }
+ return super.handleIdentifierError( token, ex );
+ }
+
+ public void handleDotIdent() throws TokenStreamException {
+ // This handles HHH-354, where there is a strange property name in a where
clause.
+ // If the lookahead contains a DOT then something that isn't an IDENT...
+ handleDotIdent( 1 );
+ }
+
+ protected int handleDotIdent(int offset) throws TokenStreamException {
+ while ( LA( offset ) == DOT ) {
+ switch ( LA( offset+1 ) ) {
+ case IDENT:
+ case CLASS:
+ break; // break the case statement, not the loop...
+ default:
+ convertPossibleIdentifier( ( TokenImpl ) LT( offset+1 ) );
+ }
+ offset += 2;
+ }
+ return offset;
+ }
+
+ protected void weakKeywords() throws TokenStreamException {
+ switch ( LA( 1 ) ) {
+ case IDENT:
+ break;
+ default :
+ if ( LA(0) == FROM && LA(2) == DOT ) {
+ convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+ }
+ }
+ }
+
+ protected void unequivocalKeywordAsIdentifier() throws TokenStreamException {
+ if ( LA(1) == IDENT ) {
+ return;
+ }
+ convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+ }
+
+ protected void potentialUpdatePersisterAlias() throws TokenStreamException {
+ switch( LA(1) ) {
+ case AS:
+ // alias rule will handle this...
+ case SET:
+ // SET marks the beginning of the UPDATE's SET-clause
+ break;
+ default:
+ convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+ }
+ }
+
+ protected void potentialDeletePersisterAlias() throws TokenStreamException {
+ switch( LA(1) ) {
+ case AS:
+ // alias rule will handle this...
+ case WHERE:
+ break;
+ default:
+ convertPossibleIdentifier( ( TokenImpl ) LT(1) );
+ }
+ }
+
+ protected void prepareForPersisterReferenceRoot() throws TokenStreamException {
+ if ( LA(1) == IN ) {
+ return;
+ }
+
+ unequivocalKeywordAsIdentifier();
+
+ if ( LA(1) == IDENT && LA(2) == IN ) {
+ return;
+ }
+
+ prepareForBasicEntityPersisterReference();
+ }
+
+ protected void prepareForCrossJoinElements() throws TokenStreamException {
+ unequivocalKeywordAsIdentifier();
+ prepareForBasicEntityPersisterReference();
+ }
+
+ protected void prepareForBasicEntityPersisterReference() throws TokenStreamException {
+ int offset = handleDotIdent( 2 );
+ int next = LA(offset);
+ switch ( next ) {
+ case AS: {
+ // the next token would need to be the persister alias
+ convertPossibleIdentifier( (TokenImpl) LT(offset+1) );
+ break;
+ }
+ case IDENT : {
+ // nothing to do
+ break;
+ }
+ case WHERE:
+ case COMMA:
+ case ON:
+ case WITH:
+ case JOIN:
+ case RIGHT:
+ case LEFT:
+ case CROSS: {
+ // single token structural elements indicating that the next thing could not be an
alias
+ break;
+ }
+ case UNION:
+ case INTERSECT:
+ case EXCEPT: {
+ int nextNext = LA(offset+1);
+ if ( nextNext == SELECT || nextNext == FROM ) {
+ break;
+ }
+ else if ( nextNext == ALL ) {
+ int nextNextNext = LA(offset+2);
+ if ( nextNextNext == SELECT || nextNextNext == FROM ) {
+ break;
+ }
+ }
+ convertPossibleIdentifier( ( TokenImpl ) LT(offset) );
+ break;
+ }
+ case FETCH:
+ if ( ! ( LA(offset+1) == ALL && LA(offset+2) == PROPERTIES ) ) {
+ // not sure sure I like allowing 'fetch' as an indentifier
+ log.warn( "interpretting [fetch] keyword as alias; consider using differen
alias" );
+ convertPossibleIdentifier( ( TokenImpl ) LT(offset) );
+ }
+ break;
+ default:
+ convertPossibleIdentifier( ( TokenImpl ) LT(offset) );
+ break;
+ }
+ }
+
+ protected void prepareForQualifiedJoinElements() throws TokenStreamException {
+ unequivocalKeywordAsIdentifier();
+ prepareForBasicEntityPersisterReference();
+ }
+
+ protected void convertPossibleIdentifier(TokenImpl token) {
+ if ( token.isPossibleIdentifier() && token.getType() != IDENT ) {
+ log.debug( "Converting keyword [{}] to identifier",
printer.getTokenTypeName( token.getType() ) );
+ token.setType( IDENT );
+ }
+ }
+
+ private static Context wrapInContext(final SessionFactoryImplementor
sessionFactoryImplementor) {
+ return new Context() {
+ public boolean isEntityName(String name) {
+ return findEntityPersisterByName( name ) != null;
+ }
+
+ public String getImportedName(String name) {
+ return sessionFactoryImplementor.getImportedClassName( name );
+ }
+
+ public boolean isRegisteredFunctionName(String name) {
+ return sessionFactoryImplementor.getDialect().getFunctions().get( name ) != null;
+ }
+
+ private EntityPersister findEntityPersisterByName(String name) throws MappingException
{
+ try {
+ return sessionFactoryImplementor.getEntityPersister( name );
+ }
+ catch ( MappingException ignore ) {
+ // unable to locate it using this name
+ }
+
+ // If that didn't work, try using the 'import' name.
+ String importedClassName = sessionFactoryImplementor.getImportedClassName( name );
+ if ( importedClassName == null ) {
+ return null;
+ }
+ return sessionFactoryImplementor.getEntityPersister( importedClassName );
+ }
+ };
+ }
+
+ public static interface Context {
+ /**
+ * Does this name represent an entity name?
+ *
+ * @param name The name to check
+ * @return True if the name represents an entioty name; false otherwise.
+ */
+ public boolean isEntityName(String name);
+
+ /**
+ * Get the import "replacement" name for the given name (e.g., 'User'
-> 'com.acme.User'). <tt>null</tt>
+ * indicates an unrecognized name.
+ *
+ * @param name The name for which to locate the imported name.
+ * @return The corresponding imported name, or null.
+ */
+ public String getImportedName(String name);
+
+ /**
+ * Does the given name represent a registered function name?
+ *
+ * @param name The name to check
+ * @return True if the name matches a registered function name; false otherwise.
+ */
+ public boolean isRegisteredFunctionName(String name);
+ }
+}
Copied:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java
(from rev 15693,
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/hql/ast/phase/parse/PathCollector.java)
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/phase/hql/parse/PathCollector.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,61 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.parse;
+
+import antlr.collections.AST;
+
+/**
+ * Utilizes a NodeTraverser in order to collect a path from
+ * (expecting dot-structure) an AST.
+ *
+ * @author Steve Ebersole
+ */
+public class PathCollector implements HqlParseTokenTypes {
+
+ /**
+ * Direct instantiation of PathCollector disallowed.
+ */
+ private PathCollector() {
+ }
+
+ public static String getPath(AST dotStructure) {
+ if ( dotStructure.getType() == IDENT ) {
+ return dotStructure.getText();
+ }
+
+ return extractText( dotStructure );
+ }
+
+ private static String extractText(AST node) {
+ AST lhs = node.getFirstChild();
+ AST rhs = lhs.getNextSibling();
+
+ if ( lhs.getType() == IDENT ) {
+ return lhs.getText() + node.getText() + rhs.getText();
+ }
+ else {
+ return extractText( lhs ) + node.getText() + rhs.getText();
+ }
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTChildIterator.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2009, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.util;
+
+import java.util.Iterator;
+
+import antlr.collections.AST;
+
+/**
+ * Iteration of an AST tree bounded to a given level of children.
+ *
+ * @author Steve Ebersole
+ */
+public class ASTChildIterator implements Iterator {
+
+ private AST next;
+
+ public ASTChildIterator(AST next) {
+ this.next = next;
+ }
+
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ public Object next() {
+ AST rtn = next;
+ next = next.getNextSibling();
+ return rtn;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException( "remove() is not supported" );
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/ASTPrinter.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -26,7 +26,6 @@
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;
@@ -215,8 +214,7 @@
}
}
- public static String escapeMultibyteChars(String text)
- {
+ public static String escapeMultibyteChars(String text) {
StringBuffer buf = new StringBuffer();
appendEscapedMultibyteChars(text,buf);
return buf.toString();
Added:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/sql/ast/util/NodeDeepCopier.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,56 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.util;
+
+import antlr.collections.AST;
+import antlr.ASTFactory;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class NodeDeepCopier {
+ private final ASTFactory astFactory;
+
+ public NodeDeepCopier(ASTFactory astFactory) {
+ this.astFactory = astFactory;
+ }
+
+ public AST copy(AST node) {
+ AST newNode = createShallowCopy( node );
+ AST child = node.getFirstChild();
+ while ( child != null ) {
+ newNode.addChild( copy( child ) );
+ child = child.getNextSibling();
+ }
+ return newNode;
+ }
+
+ public AST createShallowCopy(AST node) {
+ AST newNode = astFactory.create( node.getType(), node.getText() );
+ newNode.initialize( node );
+ return newNode;
+ }
+}
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/ReflectHelper.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -32,6 +32,7 @@
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.PropertyNotFoundException;
+import org.hibernate.HibernateException;
import org.hibernate.property.BasicPropertyAccessor;
import org.hibernate.property.DirectPropertyAccessor;
import org.hibernate.property.Getter;
@@ -276,6 +277,24 @@
}
}
+ public static Object getConstantValueStrictly(String name) {
+ String className = StringHelper.qualifier( name );
+ String fieldName = StringHelper.unqualify( name );
+ try {
+ Class clazz = classForName( className );
+ return clazz.getField( fieldName ).get( null );
+ }
+ catch ( ClassNotFoundException cnfe ) {
+ throw new HibernateException( "Could not locate class containing constant ["
+ className + "]" );
+ }
+ catch ( IllegalAccessException e ) {
+ throw new HibernateException( "Could not access specified field [" + name +
"]" );
+ }
+ catch ( NoSuchFieldException e ) {
+ throw new HibernateException( "Could not locate specified filed [" + name +
"]" );
+ }
+ }
+
/**
* Retrieve the default (no arg) constructor from the given class.
*
Modified:
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/main/java/org/hibernate/util/StringHelper.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -27,6 +27,7 @@
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.ArrayList;
+import java.util.Arrays;
public final class StringHelper {
@@ -85,6 +86,11 @@
return buf.toString();
}
+ public static String repeat(char character, int times) {
+ char[] buffer = new char[times];
+ Arrays.fill( buffer, character );
+ return new String( buffer );
+ }
public static String replace(String template, String placeholder, String replacement) {
return replace( template, placeholder, replacement, false );
Modified:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java 2009-01-06
17:14:14 UTC (rev 15746)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/TemplateTest.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -31,7 +31,7 @@
import org.hibernate.persister.entity.PropertyMapping;
import org.hibernate.type.Type;
import org.hibernate.QueryException;
-import org.hibernate.sql.ordering.antlr.ColumnMapper;
+import org.hibernate.sql.ast.ordering.ColumnMapper;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.function.SQLFunctionRegistry;
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Address.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,77 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * Implementation of Address.
+ *
+ * @author Steve Ebersole
+ */
+public class Address {
+ private String street;
+ private String city;
+ private String postalCode;
+ private String country;
+ private StateProvince stateProvince;
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getPostalCode() {
+ return postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public StateProvince getStateProvince() {
+ return stateProvince;
+ }
+
+ public void setStateProvince(StateProvince stateProvince) {
+ this.stateProvince = stateProvince;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Animal.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,121 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * @author Gavin King
+ */
+public class Animal {
+ private Long id;
+ private float bodyWeight;
+ private Set offspring;
+ private Animal mother;
+ private Animal father;
+ private String description;
+ private Zoo zoo;
+ private String serialNumber;
+
+ public Animal() {
+ }
+
+ public Animal(String description, float bodyWeight) {
+ this.description = description;
+ this.bodyWeight = bodyWeight;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public float getBodyWeight() {
+ return bodyWeight;
+ }
+
+ public void setBodyWeight(float bodyWeight) {
+ this.bodyWeight = bodyWeight;
+ }
+
+ public Set getOffspring() {
+ return offspring;
+ }
+
+ public void addOffspring(Animal offspring) {
+ if ( this.offspring == null ) {
+ this.offspring = new HashSet();
+ }
+
+ this.offspring.add( offspring );
+ }
+
+ public void setOffspring(Set offspring) {
+ this.offspring = offspring;
+ }
+
+ public Animal getMother() {
+ return mother;
+ }
+
+ public void setMother(Animal mother) {
+ this.mother = mother;
+ }
+
+ public Animal getFather() {
+ return father;
+ }
+
+ public void setFather(Animal father) {
+ this.father = father;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Zoo getZoo() {
+ return zoo;
+ }
+
+ public void setZoo(Zoo zoo) {
+ this.zoo = zoo;
+ }
+
+ public String getSerialNumber() {
+ return serialNumber;
+ }
+
+ public void setSerialNumber(String serialNumber) {
+ this.serialNumber = serialNumber;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Cat.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Cat extends DomesticAnimal {
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Classification.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,101 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * Mimic a JDK 5 enum.
+ *
+ * @author Steve Ebersole
+ */
+public class Classification implements Serializable, Comparable {
+
+ public static final Classification COOL = new Classification( "COOL", 0 );
+ public static final Classification LAME = new Classification( "LAME", 1 );
+
+ private static final HashMap INSTANCES = new HashMap();
+ static {
+ INSTANCES.put( COOL.name, COOL );
+ INSTANCES.put( LAME.name, LAME );
+ }
+
+ private final String name;
+ private final int ordinal;
+ private final int hashCode;
+
+ private Classification(String name, int ordinal) {
+ this.name = name;
+ this.ordinal = ordinal;
+
+ int hashCode = name.hashCode();
+ hashCode = 29 * hashCode + ordinal;
+ this.hashCode = hashCode;
+ }
+
+ public String name() {
+ return name;
+ }
+
+ public int ordinal() {
+ return ordinal;
+ }
+
+ public boolean equals(Object obj) {
+ return compareTo( obj ) == 0;
+ }
+
+ public int compareTo(Object o) {
+ int otherOrdinal = ( ( Classification ) o ).ordinal;
+ if ( ordinal == otherOrdinal ) {
+ return 0;
+ }
+ else if ( ordinal > otherOrdinal ) {
+ return 1;
+ }
+ else {
+ return -1;
+ }
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public static Classification valueOf(String name) {
+ return ( Classification ) INSTANCES.get( name );
+ }
+
+ public static Classification valueOf(Integer ordinal) {
+ if ( ordinal == null ) {
+ return null;
+ }
+ switch ( ordinal.intValue() ) {
+ case 0: return COOL;
+ case 1: return LAME;
+ default: throw new IllegalArgumentException( "unknown classification ordinal
[" + ordinal + "]" );
+ }
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/ClassificationType.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,124 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import org.hibernate.usertype.EnhancedUserType;
+import org.hibernate.HibernateException;
+import org.hibernate.Hibernate;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+import java.io.Serializable;
+
+/**
+ * A custom type for mapping {@link Classification} instances
+ * to the respective db column.
+ * </p>
+ * THis is largely intended to mimic JDK5 enum support in JPA. Here we are
+ * using the approach of storing the ordinal values, rather than the names.
+ *
+ * @author Steve Ebersole
+ */
+public class ClassificationType implements EnhancedUserType {
+
+ public int[] sqlTypes() {
+ return new int[] { Types.TINYINT };
+ }
+
+ public Class returnedClass() {
+ return Classification.class;
+ }
+
+ public boolean equals(Object x, Object y) throws HibernateException {
+ if ( x == null && y == null ) {
+ return false;
+ }
+ else if ( x != null ) {
+ return x.equals( y );
+ }
+ else {
+ return y.equals( x );
+ }
+ }
+
+ public int hashCode(Object x) throws HibernateException {
+ return x.hashCode();
+ }
+
+ public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws
HibernateException, SQLException {
+ Integer ordinal = ( Integer ) Hibernate.INTEGER.nullSafeGet( rs, names[0] );
+ return Classification.valueOf( ordinal );
+ }
+
+ public void nullSafeSet(PreparedStatement st, Object value, int index) throws
HibernateException, SQLException {
+ Integer ordinal = value == null ? null : new Integer( ( ( Classification ) value
).ordinal() );
+ Hibernate.INTEGER.nullSafeSet( st, ordinal, index );
+ }
+
+ public Object deepCopy(Object value) throws HibernateException {
+ return value;
+ }
+
+ public boolean isMutable() {
+ return false;
+ }
+
+ public Serializable disassemble(Object value) throws HibernateException {
+ return ( Classification ) value;
+ }
+
+ public Object assemble(Serializable cached, Object owner) throws HibernateException {
+ return cached;
+ }
+
+ public Object replace(Object original, Object target, Object owner) throws
HibernateException {
+ return original;
+ }
+
+ public String objectToSQLString(Object value) {
+ return extractOrdinalString( value );
+ }
+
+ public String toXMLString(Object value) {
+ return extractName( value );
+ }
+
+ public Object fromXMLString(String xmlValue) {
+ return Classification.valueOf( xmlValue );
+ }
+
+ private String extractName(Object obj) {
+ return ( ( Classification ) obj ).name();
+ }
+
+ private int extractOrdinal(Object value) {
+ return ( ( Classification ) value ).ordinal();
+ }
+
+ private String extractOrdinalString(Object value) {
+ return Integer.toString( extractOrdinal( value ) );
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Dog.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Dog extends DomesticAnimal {
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/DomesticAnimal.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,39 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class DomesticAnimal extends Mammal {
+ private Human owner;
+
+ public Human getOwner() {
+ return owner;
+ }
+
+ public void setOwner(Human owner) {
+ this.owner = owner;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Human.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,148 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Gavin King
+ */
+public class Human extends Mammal {
+ private Name name;
+ private String nickName;
+ private Collection friends;
+ private Collection pets;
+ private Map family;
+ private double height;
+
+ private BigInteger bigIntegerValue;
+ private BigDecimal bigDecimalValue;
+ private int intValue;
+ private float floatValue;
+
+ private Set nickNames;
+ private Map addresses;
+
+ public Collection getFriends() {
+ return friends;
+ }
+
+ public void setFriends(Collection friends) {
+ this.friends = friends;
+ }
+
+ public Collection getPets() {
+ return pets;
+ }
+
+ public void setPets(Collection pets) {
+ this.pets = pets;
+ }
+
+ public Name getName() {
+ return name;
+ }
+
+ public void setName(Name name) {
+ this.name = name;
+ }
+
+ public String getNickName() {
+ return nickName;
+ }
+
+ public void setNickName(String nickName) {
+ this.nickName = nickName;
+ }
+
+ public double getHeight() {
+ return height;
+ }
+ public void setHeight(double height) {
+ this.height = height;
+ }
+
+ public Map getFamily() {
+ return family;
+ }
+
+
+ public void setFamily(Map family) {
+ this.family = family;
+ }
+
+ public Set getNickNames() {
+ return nickNames;
+ }
+
+ public void setNickNames(Set nickNames) {
+ this.nickNames = nickNames;
+ }
+
+ public Map getAddresses() {
+ return addresses;
+ }
+
+ public void setAddresses(Map addresses) {
+ this.addresses = addresses;
+ }
+
+ public BigDecimal getBigDecimalValue() {
+ return bigDecimalValue;
+ }
+
+ public void setBigDecimalValue(BigDecimal bigDecimalValue) {
+ this.bigDecimalValue = bigDecimalValue;
+ }
+
+ public BigInteger getBigIntegerValue() {
+ return bigIntegerValue;
+ }
+
+ public void setBigIntegerValue(BigInteger bigIntegerValue) {
+ this.bigIntegerValue = bigIntegerValue;
+ }
+
+ public float getFloatValue() {
+ return floatValue;
+ }
+
+ public void setFloatValue(float floatValue) {
+ this.floatValue = floatValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(int intValue) {
+ this.intValue = intValue;
+ }
+
+
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Joiner.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * Implementation of Joiner.
+ *
+ * @author Steve Ebersole
+ */
+public class Joiner {
+ private Long id;
+ private String name;
+ private String joinedName;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getJoinedName() {
+ return joinedName;
+ }
+
+ public void setJoinedName(String joinedName) {
+ this.joinedName = joinedName;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Lizard.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,31 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Lizard extends Reptile {
+
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mammal.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,52 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.util.Date;
+
+/**
+ * @author Gavin King
+ */
+public class Mammal extends Animal {
+ private boolean pregnant;
+ private Date birthdate;
+
+ public boolean isPregnant() {
+ return pregnant;
+ }
+
+ public void setPregnant(boolean pregnant) {
+ this.pregnant = pregnant;
+ }
+
+ public Date getBirthdate() {
+ return birthdate;
+ }
+
+
+ public void setBirthdate(Date birthdate) {
+ this.birthdate = birthdate;
+ }
+
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,166 @@
+<?xml version="1.0"?>
+<!--
+ ~ Hibernate, Relational Persistence for Idiomatic Java
+ ~
+ ~ Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ ~ indicated by the @author tags or express copyright attribution
+ ~ statements applied by the authors. All third-party contributions are
+ ~ distributed under license by Red Hat Middleware LLC.
+ ~
+ ~ This copyrighted material is made available to anyone wishing to use, modify,
+ ~ copy, or redistribute it subject to the terms and conditions of the GNU
+ ~ Lesser General Public License, as published by the Free Software Foundation.
+ ~
+ ~ This program is distributed in the hope that it will be useful,
+ ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ~ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ ~ for more details.
+ ~
+ ~ You should have received a copy of the GNU Lesser General Public License
+ ~ along with this distribution; if not, write to:
+ ~ Free Software Foundation, Inc.
+ ~ 51 Franklin Street, Fifth Floor
+ ~ Boston, MA 02110-1301 USA
+ -->
+<!DOCTYPE hibernate-mapping SYSTEM
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
+
+<hibernate-mapping package="org.hibernate.sql.ast.phase.hql.domain"
default-access="field">
+
+ <class name="Animal">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="description"/>
+ <property name="bodyWeight" column="body_weight"/>
+ <many-to-one name="mother" column="mother_id"/>
+ <many-to-one name="father" column="father_id"/>
+ <many-to-one name="zoo" column="zoo_id"/>
+ <property name="serialNumber"/>
+ <set name="offspring" order-by="father_id">
+ <key column="mother_id"/>
+ <one-to-many class="Animal"/>
+ </set>
+ <joined-subclass name="Reptile">
+ <key column="animal"/>
+ <property name="bodyTemperature"/>
+ <joined-subclass name="Lizard">
+ <key column="reptile"/>
+ </joined-subclass>
+ </joined-subclass>
+ <joined-subclass name="Mammal">
+ <key column="animal"/>
+ <property name="pregnant"/>
+ <property name="birthdate" type="date"/>
+ <joined-subclass name="DomesticAnimal">
+ <key column="mammal"/>
+ <many-to-one name="owner"/>
+ <joined-subclass name="Cat">
+ <key column="mammal"/>
+ </joined-subclass>
+ <joined-subclass name="Dog">
+ <key column="mammal"/>
+ </joined-subclass>
+ </joined-subclass>
+ <joined-subclass name="Human">
+ <key column="mammal"/>
+ <component name="name">
+ <property name="first" column="name_first"/>
+ <property name="initial" column="name_initial"/>
+ <property name="last" column="name_last"/>
+ </component>
+ <property name="nickName"/>
+ <property name="height"/>
+ <bag name="friends">
+ <key column="human1"/>
+ <many-to-many column="human2" class="Human"/>
+ </bag>
+ <map name="family">
+ <key column="human1"/>
+ <map-key column="relationship" type="string"/>
+ <many-to-many column="human2" class="Human"/>
+ </map>
+ <bag name="pets" inverse="true">
+ <key column="owner"/>
+ <one-to-many class="DomesticAnimal"/>
+ </bag>
+ <set name="nickNames" lazy="false"
table="human_nick_names" sort="natural">
+ <key column="human"/>
+ <element column="nick_name" type="string"
not-null="true"/>
+ </set>
+ <map name="addresses" table="addresses">
+ <key column="human"/>
+ <map-key type="string" column="type"/>
+ <composite-element class="Address">
+ <property name="street"/>
+ <property name="city"/>
+ <property name="postalCode"/>
+ <property name="country"/>
+ <many-to-one name="stateProvince"
column="state_prov_id" class="StateProvince"/>
+ </composite-element>
+ </map>
+ </joined-subclass>
+ </joined-subclass>
+ </class>
+<!--
+ <class name="User" table="`User`">
+ <id name="id">
+ <generator class="foreign">
+ <param name="property">human</param>
+ </generator>
+ </id>
+ <property name="userName"/>
+ <one-to-one name="human" constrained="true"/>
+ <list name="permissions">
+ <key column="userId"/>
+ <list-index column="permissionId"/>
+ <element type="string" column="permissionName"/>
+ </list>
+ </class>
+-->
+ <class name="Zoo" discriminator-value="Z">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <discriminator column="zooType" type="character"/>
+ <property name="name" type="string"/>
+ <property name="classification"
type="org.hibernate.sql.ast.phase.hql.domain.ClassificationType"/>
+ <map name="mammals">
+ <key column="mammalZoo_id"/>
+ <index type="string" column="name"/>
+ <one-to-many class="Mammal"/>
+ </map>
+ <map name="animals" inverse="true">
+ <key column="zoo_id"/>
+ <index type="string" column="serialNumber"/>
+ <one-to-many class="Animal"/>
+ </map>
+ <component name="address" class="Address">
+ <property name="street"/>
+ <property name="city"/>
+ <property name="postalCode"/>
+ <property name="country"/>
+ <many-to-one name="stateProvince"
column="state_prov_id" class="StateProvince"/>
+ </component>
+ <subclass name="PettingZoo" discriminator-value="P"/>
+ </class>
+
+ <class name="StateProvince">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <property name="isoCode"/>
+ </class>
+
+ <class name="Joiner">
+ <id name="id">
+ <generator class="native"/>
+ </id>
+ <property name="name"/>
+ <join table="JOINED">
+ <key column="ID"/>
+ <property name="joinedName"/>
+ </join>
+ </class>
+
+</hibernate-mapping>
\ No newline at end of file
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Name.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,69 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Name {
+ private String first;
+ private Character initial;
+ private String last;
+
+ protected Name() {}
+
+ public Name(String first, Character initial, String last) {
+ this.first = first;
+ this.initial = initial;
+ this.last = last;
+ }
+
+ public Name(String first, char initial, String last) {
+ this( first, new Character( initial ), last );
+ }
+
+ public String getFirst() {
+ return first;
+ }
+
+ public void setFirst(String first) {
+ this.first = first;
+ }
+
+ public Character getInitial() {
+ return initial;
+ }
+
+ public void setInitial(Character initial) {
+ this.initial = initial;
+ }
+
+ public String getLast() {
+ return last;
+ }
+
+ public void setLast(String last) {
+ this.last = last;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/PettingZoo.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,30 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class PettingZoo extends Zoo {
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Reptile.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,37 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * @author Gavin King
+ */
+public class Reptile extends Animal {
+ private float bodyTemperature;
+ public float getBodyTemperature() {
+ return bodyTemperature;
+ }
+ public void setBodyTemperature(float bodyTemperature) {
+ this.bodyTemperature = bodyTemperature;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/StateProvince.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,59 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+/**
+ * Implementation of StateProvince.
+ *
+ * @author Steve Ebersole
+ */
+public class StateProvince {
+ private Long id;
+ private String name;
+ private String isoCode;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getIsoCode() {
+ return isoCode;
+ }
+
+ public void setIsoCode(String isoCode) {
+ this.isoCode = isoCode;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/domain/Zoo.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,86 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.domain;
+
+import java.util.Map;
+
+/**
+ * @author Gavin King
+ */
+public class Zoo {
+ private Long id;
+ private String name;
+ private Classification classification;
+ private Map animals;
+ private Map mammals;
+ private Address address;
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Map getMammals() {
+ return mammals;
+ }
+
+ public void setMammals(Map mammals) {
+ this.mammals = mammals;
+ }
+
+ public Map getAnimals() {
+ return animals;
+ }
+
+ public void setAnimals(Map animals) {
+ this.animals = animals;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public Classification getClassification() {
+ return classification;
+ }
+
+ public void setClassification(Classification classification) {
+ this.classification = classification;
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/normalize/NormalizerTest.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,356 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ */
+package org.hibernate.sql.ast.phase.hql.normalize;
+
+import java.util.Iterator;
+
+import junit.framework.TestCase;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.HSQLDialect;
+import org.hibernate.sql.ast.util.NodeTraverser;
+import org.hibernate.sql.ast.phase.hql.normalize.HqlNormalizer;
+import org.hibernate.sql.ast.phase.hql.normalize.QuerySpec;
+import org.hibernate.sql.ast.phase.hql.normalize.SelectItem;
+import org.hibernate.sql.ast.phase.hql.normalize.SelectStatement;
+import org.hibernate.sql.ast.phase.hql.parse.ParserTest;
+import org.hibernate.sql.ast.phase.hql.domain.Animal;
+import org.hibernate.sql.ast.common.JoinType;
+import org.hibernate.hql.QuerySplitter;
+
+import antlr.collections.AST;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+
+/**
+ * TODO : javadoc
+ *
+ * @author Steve Ebersole
+ */
+public class NormalizerTest extends TestCase implements HqlNormalizeTokenTypes {
+ private SessionFactoryImplementor sessionFactory;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ sessionFactory = ( SessionFactoryImplementor ) new Configuration()
+ .setProperty( Environment.HBM2DDL_AUTO, "none" )
+ .setProperty( Environment.DIALECT, HSQLDialect.class.getName() )
+ .addResource( "org/hibernate/sql/ast/phase/hql/domain/Mappings.hbm.xml" )
+ .buildSessionFactory();
+ }
+
+ protected void tearDown() throws Exception {
+ if ( sessionFactory != null ) {
+ sessionFactory.close();
+ }
+ super.tearDown();
+ }
+
+ public void testBasicStructure() throws Throwable {
+ AST query = resolve( "select a from Animal a order by a.name" );
+ assertEquals( query.getType(), QUERY );
+
+ AST querySpec = query.getFirstChild();
+ assertEquals( QUERY_SPEC, querySpec.getType() );
+
+ AST selectFrom = querySpec.getFirstChild();
+ assertEquals( SELECT_FROM, selectFrom.getType() );
+
+ AST from = selectFrom.getFirstChild();
+ assertEquals( FROM, from.getType() );
+ assertSame( from, ( ( QuerySpec ) querySpec ).locateFromClause() );
+
+ AST select = from.getNextSibling();
+ assertEquals( SELECT, select.getType() );
+ assertSame( select, ( ( QuerySpec ) querySpec ).locateSelectClause() );
+
+ assertEquals( SELECT_LIST, select.getFirstChild().getType() );
+ assertEquals( SELECT_ITEM, select.getFirstChild().getFirstChild().getType() );
+
+ AST sorting = querySpec.getNextSibling();
+ assertEquals( ORDER_BY, sorting.getType() );
+
+ }
+
+ public void testSimpleHql() throws Exception {
+ // First, get an AST by parsing some HQL text.
+ AST ast = resolve( "from Animal" );
+ // Assert:
+ assertEquals( ast.getType(), QUERY );
+ }
+
+ public void testSimpleExplicitJoins() throws Throwable {
+ AST ast = resolve( "from Animal as a inner join a.mother as m" );
+ JoinCounter.assertJoinCount( 1, ast );
+
+ ast = resolve( "from Animal as a inner join a.offspring as c inner join a.mother
as m" );
+ JoinCounter.assertJoinCount( 2, ast );
+ }
+
+ public void testPathedExplicitJoins() throws Throwable {
+ AST ast = resolve( "from Animal as a inner join a.mother.father.offspring as
auntsanduncles" );
+ JoinCounter.assertJoinCount( 3, ast );
+ }
+
+ public void testSelectPersisterReference() throws Throwable {
+ AST query = resolve( "select a from Animal a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectItemCounter.assertSelectItemCount( 1, query );
+
+ assertEquals( query.getType(), QUERY );
+ AST selectClause =
query.getFirstChild().getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( SELECT, selectClause.getType() );
+ AST selectItem = selectClause.getFirstChild().getFirstChild();
+ assertEquals( SELECT_ITEM, selectItem.getType() );
+ AST aliasRef = selectItem.getFirstChild();
+ assertEquals( ALIAS_REF, aliasRef.getType() );
+ assertEquals( "a", aliasRef.getText() );
+ }
+
+ public void testSelectAssociationPropertyReference() throws Throwable {
+ // todo : implicit joins...
+ AST query = resolve( "select a.mother as m from Animal as a" );
+ JoinCounter.assertJoinCount( 1, query );
+
+ assertTrue( query instanceof SelectStatement );
+ QuerySpec querySpec = ( ( SelectStatement ) query ).locateQuerySpec();
+ AST persisterSpace = querySpec.locateFromClause().getFirstChild();
+ assertEquals( PERSISTER_SPACE, persisterSpace.getType() );
+ EntityPersisterReference entityPersisterReference = ( EntityPersisterReference )
persisterSpace.getFirstChild();
+ Iterator itr = entityPersisterReference.locateJoins();
+ assertTrue( itr.hasNext() );
+ Join join = ( Join ) itr.next();
+ assertFalse( itr.hasNext() );
+ assertEquals( JoinType.INNER, join.getEnumeratedJoinType() );
+ PersisterReference rhs = join.getRhs();
+ assertEquals( Animal.class.getName(), rhs.getName() );
+ // this should work since there is only one non-explicit persister alias...
+ assertEquals( "<gen:0>", rhs.getAlias() );
+
+ SelectItemCounter.assertSelectItemCount( 1, query );
+ AST selectList = querySpec.locateSelectClause().getFirstChild();
+ assertEquals( SELECT_LIST, selectList.getType() );
+ assertEquals( 1, selectList.getNumberOfChildren() );
+ SelectItem selectItem = ( SelectItem ) selectList.getFirstChild();
+ assertEquals( "m", selectItem.getAliasText() );
+ PropertyReference propertyReference = ( PropertyReference )
selectItem.getSelectExpression();
+ assertEquals( ALIAS_REF, propertyReference.getFirstChild().getType() );
+ assertEquals( "a", propertyReference.getFirstChild().getText() );
+ assertEquals( "a.mother", propertyReference.getNormalizedPath() );
+ }
+
+ public void testSimpleSimplePropertyReference() throws Throwable {
+ AST query = resolve( "select a.name as m from Animal as a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectItemCounter.assertSelectItemCount( 1, query );
+ assertTrue( query instanceof SelectStatement );
+ AST selectClause = ( ( QuerySpec ) query.getFirstChild() ).locateSelectClause();
+ assertNotNull( selectClause );
+ assertEquals( SELECT, selectClause.getType() );
+ assertEquals( 1, selectClause.getNumberOfChildren() );
+ AST selectList = selectClause.getFirstChild();
+ assertEquals( SELECT_LIST, selectList.getType() );
+ assertEquals( 1, selectList.getNumberOfChildren() );
+ AST selectItem = selectList.getFirstChild();
+ assertEquals( SELECT_ITEM, selectItem.getType() );
+ AST selectExpression = selectItem.getFirstChild();
+ assertEquals( PROPERTY_REF, selectExpression.getType() );
+ PropertyReference propertyReference = ( PropertyReference ) selectExpression;
+ assertEquals( "a.name", propertyReference.getNormalizedPath() );
+ assertEquals( "m", ( ( SelectItem ) selectItem ).getAliasText() );
+ }
+
+ public void testSelectPropertyRefCount() throws Throwable {
+ AST query = resolve( "select count(a.mother) from Animal as a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectItemCounter.assertSelectItemCount( 1, query );
+ assertTrue( query instanceof SelectStatement );
+ AST selectClause = ( ( QuerySpec ) query.getFirstChild() ).locateSelectClause();
+ assertNotNull( selectClause );
+ assertEquals( SELECT, selectClause.getType() );
+ assertEquals( 1, selectClause.getNumberOfChildren() );
+ AST selectList = selectClause.getFirstChild();
+ assertEquals( SELECT_LIST, selectList.getType() );
+ assertEquals( 1, selectList.getNumberOfChildren() );
+ AST selectItem = selectList.getFirstChild();
+ assertEquals( SELECT_ITEM, selectItem.getType() );
+ AST selectExpression = selectItem.getFirstChild();
+ assertEquals( COUNT, selectExpression.getType() );
+ assertEquals( "count", selectExpression.getText() );
+ }
+
+ public void testExplicitImplicitJoin() throws Exception {
+ AST ast = resolve( "from Animal a left join fetch a.mother.mother.mother as ggm
where ggm.name like '%weeble%'" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 3, ast );
+
+ ast = resolve( "from Animal as a inner join a.mother.mother as gm" );
+ JoinCounter.assertJoinCount( 2, ast );
+
+ ast = resolve( "from Animal as a inner join a.mother.father as gf" );
+ JoinCounter.assertJoinCount( 2, ast );
+
+ ast = resolve( "from Animal as a inner join a.offspring as c inner join
a.mother.father as mgf inner join fetch a.father" );
+ JoinCounter.assertJoinCount( 4, ast );
+ }
+
+ public void testExplicitCollectionJoin() throws Throwable {
+ AST ast = resolve( "from Animal as a inner join a.offspring as o where o.name like
'%boots%'" );
+ }
+
+ public void testSimpleImplicitJoin() throws Exception {
+ AST ast = resolve( "from Animal a where a.mother.name like '%mary%'"
);
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 1, ast );
+
+ ast = resolve( "from Animal a where a.mother.father.name like
'%weeble%'" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 2, ast );
+
+ ast = resolve( "from Animal a where a.mother.mother.name like
'%weeble%'" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 2, ast );
+
+ ast = resolve( "from Animal a where a.mother.mother = ?" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 1, ast );
+ }
+
+ public void testWithClause() throws Throwable {
+ resolve( "from Zoo z inner join z.mammals as m with m.name = ?" );
+ }
+
+ public void testUnqualifiedPropertyReference() throws Exception {
+ AST ast = resolve( "from Animal where name like '%mary%'" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 0, ast );
+
+ ast = resolve( "from Animal where mother.name like '%mary%'" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 1, ast );
+ }
+
+ public void testThetaJoins() throws Exception {
+ AST ast = resolve( "from Animal a, Animal b where a.mother.id = b.id and b.name
like '%mary%'" );
+ assertTrue( ast instanceof SelectStatement );
+// JoinCounter.assertJoinCount( 1, ast );
+
+ ast = resolve( "from Animal a, Animal b inner join b.mother as c where a.mother.id
= b.id and b.name like '%mary%'" );
+ assertTrue( ast instanceof SelectStatement );
+// JoinCounter.assertJoinCount( 2, ast );
+ }
+
+ public void testAdHocJoins() throws Exception {
+ resolve( "from Animal a inner join Zoo z on a.id = z.id" );
+ resolve( "from Animal a inner join Zoo z on a.id = z.id inner join z.mammals as m
with m.name = ?" );
+ }
+
+ public void testReusingImplcitJoins() throws Throwable {
+ AST ast = resolve( "from Animal a where a.mother.father.name = 'abc' and
a.mother.father.description = 'xyz'" );
+ assertTrue( ast instanceof SelectStatement );
+ JoinCounter.assertJoinCount( 2, ast );
+ }
+
+ public void testIndexOperations() throws Throwable {
+// resolve( "select o from IndexedCollectionOwner as o where
o.simpleMap['test'] = 'xyz'" );
+ resolve( "select o from IndexedCollectionOwner as o inner join o.simpleMap as s
where o.simpleMap[ index(s) ] = 'xyz'" );
+ }
+
+ public void testIndexOperations2() throws Throwable {
+ resolve( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] =
an" );
+ resolve( "from Zoo where mammals['dog'] = ?" );
+ resolve( "from Zoo zoo where zoo.mammals['dog'].father.description like
'%black%'" );
+ }
+
+
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ private AST resolve(String hql) throws RecognitionException, TokenStreamException {
+ // to be completely accurate, the incoming hql string should be run through
+ // QuerySplitter as that is what happens prior to translation and results in
+ // a different string to actually translate...
+ String[] queries = QuerySplitter.concreteQueries( hql, getSessionFactoryImplementor()
);
+ assertEquals( "polymorhpic queries not allowed here", 1, queries.length );
+ hql = queries[0];
+
+ AST hqlAst = ParserTest.doParse( hql, false );
+
+ // Now, pass it though the resolver phase, which yeilds
+ // a processed HQL AST.
+ HqlNormalizer resolver = new HqlNormalizer( sessionFactory );
+ resolver.statement( hqlAst );
+ AST resolvedHql = resolver.getAST();
+ System.out.println( resolver.getPrinter().showAsString( resolvedHql, "Resolved AST
: " + resolvedHql.toStringTree() + "" ) );
+ return resolvedHql;
+ }
+
+ protected SessionFactoryImplementor getSessionFactoryImplementor() {
+ return sessionFactory;
+ }
+
+ private static class JoinCounter implements NodeTraverser.VisitationStrategy {
+ int count = 0;
+ public void visit(AST node) {
+ if ( node.getType() == JOIN ) {
+ count++;
+ }
+ }
+ public static void assertJoinCount(int expected, AST tree) {
+ JoinCounter.assertJoinCount( "unexpected join count", expected, tree );
+ }
+ public static void assertJoinCount(String failMessage, int expected, AST tree) {
+ JoinCounter counter = new JoinCounter();
+ NodeTraverser walker = new NodeTraverser( counter );
+ walker.traverseDepthFirst( tree );
+ assertEquals( failMessage, expected, counter.count );
+ }
+ }
+
+ private static class SelectItemCounter implements NodeTraverser.VisitationStrategy {
+ int count;
+ public void visit(AST node) {
+ if ( node instanceof SelectItem ) {
+ count++;
+ }
+ }
+ public static void assertSelectItemCount(int expected, AST tree) {
+ SelectItemCounter.assertSelectItemCount( "unexpected select expression
count", expected, tree );
+ }
+ public static void assertSelectItemCount(String failMessage, int expected, AST tree) {
+ SelectItemCounter counter = new SelectItemCounter();
+ NodeTraverser walker = new NodeTraverser( counter );
+ walker.traverseDepthFirst( tree );
+ assertEquals( failMessage, expected, counter.count );
+ }
+ }
+
+ public static Test suite() {
+ return new TestSuite( NormalizerTest.class );
+ }
+}
Added:
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
===================================================================
---
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java
(rev 0)
+++
core/branches/SQL_GEN_REDESIGN/src/test/java/org/hibernate/sql/ast/phase/hql/parse/ParserTest.java 2009-01-06
20:11:13 UTC (rev 15747)
@@ -0,0 +1,1176 @@
+package org.hibernate.sql.ast.phase.hql.parse;
+
+import junit.framework.TestCase;
+import org.hibernate.sql.ast.util.ASTIterator;
+import org.hibernate.sql.ast.common.Node;
+import org.hibernate.sql.ast.util.ASTPrinter;
+import org.hibernate.sql.ast.phase.hql.parse.HqlParser;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import antlr.collections.AST;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+
+/**
+ * todo: describe ParserTest
+ *
+ * @author Steve Ebersole
+ */
+public class ParserTest extends TestCase implements HqlParseTokenTypes {
+ public static final Log log = LogFactory.getLog( ParserTest.class );
+
+ public static final String CONSTANT = "constant-value";
+
+ public void testEntityReferenceRule() throws Throwable {
+ String entityName = "com.acme.EntityName";
+ HqlParser parser = buildHqlParser( entityName );
+ parser.entityName();
+ AST result = parser.getAST();
+ show( result, "entity-name-result" );
+ assertEquals( ENTITY_NAME, result.getType() );
+ assertEquals( entityName, result.getText() );
+
+ entityName = "EntityName";
+ parser = buildHqlParser( entityName );
+ parser.entityName();
+ result = parser.getAST();
+ show( result, "entity-name-result" );
+ assertEquals( ENTITY_NAME, result.getType() );
+ assertEquals( entityName, result.getText() );
+ }
+
+ public void testSimpleFrom() throws Throwable {
+ String entityName = "com.acme.EntityName";
+ HqlParser parser = buildHqlParser( "from " + entityName + " e" );
+ parser.statement();
+ AST result = parser.getAST();
+ show( result, "simple-from-result" );
+ }
+
+ public void testConstantUsage() throws Throwable {
+ HqlParser parser = buildHqlParser( "from com.acme.EntityName where prop =
org.hibernate.sql.ast.phase.hql.parse.ParserTest.CONSTANT" );
+ parser.statement();
+ AST result = parser.getAST();
+ show( result, "constant" );
+ AST constantNode = goToWhereClause( result
).getFirstChild().getFirstChild().getNextSibling();
+ assertEquals( JAVA_CONSTANT, constantNode.getType() );
+
+ // apply control checks
+ parser = buildHqlParser( "from com.acme.EntityName where prop =
compProp.subProp" );
+ parser.statement();
+ result = parser.getAST();
+ show( result, "constant-control" );
+ AST checkNode = goToWhereClause( result
).getFirstChild().getFirstChild().getNextSibling();
+ assertEquals( DOT, checkNode.getType() );
+ }
+
+ public AST goToWhereClause(AST query) {
+ return query.getFirstChild() // QUERY_SPEC
+ .getFirstChild() // SELECT_FROM
+ .getNextSibling(); // WHERE
+ }
+
+ public void testVariousPropertyReferences() throws Exception {
+ parse( "from A a where b = 1" );
+ parse( "from A a where a.b.c = 1" );
+ parse( "from X x where y[1].z = 2" );
+ parse( "from X x where x.y[1].z = 2" );
+ }
+
+ public void testEntityNamePathWithKeyword() throws Exception {
+ parse( "from org.hibernate.test.Inner" );
+ }
+
+ public void testWhereClauseIdentPrimaryWithEmbeddedKeyword() throws Exception {
+ parse( "from org.hibernate.test.Inner i where i.outer.inner.middle =
'xyz'" );
+ }
+
+ public void testDynamicInstantiation() throws Exception {
+ parse( "select new list(a, mate) from Animal a join a.mate as mate" );
+ parse( "select new Family(mother, mate, offspr) from eg.DomesticCat as mother join
mother.mate as mate left join mother.kittens as offspr" );
+ }
+
+ public void testListOrMapKeywordReference() throws Exception {
+ parse( "select p from eg.NameList nl, eg.Person p where p.name = some
elements(nl.names)" );
+ parse( "select p from eg.NameList list, eg.Person p where p.name = some
elements(list.names)" );
+ parse( "select p from eg.NameList map, eg.Person p where p.name = some
elements(map.names)" );
+ }
+
+ public void testExplicitPropertyJoin() throws Exception {
+ parse( "from eg.Cat as cat inner join fetch cat.mate as m fetch all properties
left join fetch cat.kittens as k" );
+ }
+
+ private static void show(AST node, String header) {
+ ASTPrinter printer = new ASTPrinter( HqlParseTokenTypes.class, false );
+ log.info( printer.showAsString( node, header ) );
+ }
+
+ // tests copied over from org.hibernate.test.hql.HqlParserTest ~~~~~~~~~~~~
+
+ public void testUnion() throws Exception {
+ parse("from Animal a where a in (from Cat union from Dog) ");
+ }
+
+ /**
+ * Section 9.2 - from *
+ */
+ public void testDocoExamples92() throws Exception {
+ parse( "from eg.Cat" );
+ parse( "from eg.Cat as cat" );
+ parse( "from eg.Cat cat" );
+ parse( "from Formula, Parameter" );
+ parse( "from Formula as form, Parameter as param" );
+ }
+
+ /**
+ * Section 9.3 - Associations and joins *
+ */
+ public void testDocoExamples93() throws Exception {
+ parse( "from eg.Cat as cat inner join cat.mate as mate left outer join cat.kittens
as kitten" );
+ parse( "from eg.Cat as cat left join cat.mate.kittens as kittens" );
+ parse( "from Formula form full join form.parameter param" );
+ parse( "from eg.Cat as cat join cat.mate as mate left join cat.kittens as
kitten" );
+ parse( "from eg.Cat as cat\ninner join fetch cat.mate\nleft join fetch
cat.kittens" );
+ }
+
+ /**
+ * Section 9.4 - Select *
+ */
+ public void testDocoExamples94() throws Exception {
+ parse( "select mate from eg.Cat as cat inner join cat.mate as mate" );
+ parse( "select cat.mate from eg.Cat cat" );
+ parse( "select elements(cat.kittens) from eg.Cat cat" );
+ parse( "select cat.name from eg.DomesticCat cat where cat.name like
'fri%'" );
+ parse( "select cust.name.firstName from Customer as cust" );
+ parse( "select mother, offspr, mate.name from eg.DomesticCat\n"
+ + " as mother inner join mother.mate as mate left outer join\n"
+ + "mother.kittens as offspr" );
+ parse( "select new Family(mother, mate, offspr)\n"
+ + "from eg.DomesticCat as mother\n"
+ + "join mother.mate as mate\n"
+ + "left join mother.kittens as offspr\n" );
+ }
+
+ /**
+ * Section 9.5 - Aggregate functions *
+ */
+ public void testDocoExamples95() throws Exception {
+ parse( "select avg(cat.weight), sum(cat.weight), max(cat.weight),
count(cat)\n"
+ + "from eg.Cat cat" );
+ parse( "select cat, count( elements(cat.kittens) )\n"
+ + " from eg.Cat cat group by cat" );
+ parse( "select distinct cat.name from eg.Cat cat" );
+ parse( "select count(distinct cat.name), count(cat) from eg.Cat cat" );
+ }
+
+ /**
+ * Section 9.6 - Polymorphism *
+ */
+ public void testDocoExamples96() throws Exception {
+ parse( "from eg.Cat as cat" );
+ parse( "from java.lang.Object o" );
+ parse( "from eg.Named n, eg.Named m where n.name = m.name" );
+ }
+
+ /**
+ * Section 9.7 - Where *
+ */
+ public void testDocoExamples97() throws Exception {
+ parse( "from eg.Cat as cat where cat.name='Fritz'" );
+ parse( "select foo\n"
+ + "from eg.Foo foo, eg.Bar bar\n"
+ + "where foo.startDate = bar.date\n" );
+ parse( "from eg.Cat cat where cat.mate.name is not null" );
+ parse( "from eg.Cat cat, eg.Cat rival where cat.mate = rival.mate" );
+ parse( "select cat, mate\n"
+ + "from eg.Cat cat, eg.Cat mate\n"
+ + "where cat.mate = mate" );
+ parse( "from eg.Cat as cat where cat.id = 123" );
+ parse( "from eg.Cat as cat where cat.mate.id = 69" );
+ parse( "from bank.Person person\n"
+ + "where person.id.country = 'AU'\n"
+ + "and person.id.medicareNumber = 123456" );
+ parse( "from bank.Account account\n"
+ + "where account.owner.id.country = 'AU'\n"
+ + "and account.owner.id.medicareNumber = 123456" );
+ parse( "from eg.Cat cat where cat.class = eg.DomesticCat" );
+ parse( "from eg.AuditLog log, eg.Payment payment\n"
+ + "where log.item.class = 'eg.Payment' and log.item.id =
payment.id" );
+ }
+
+ /**
+ * Section 9.8 - Expressions *
+ */
+ public void testDocoExamples98() throws Exception {
+ parse( "from eg.DomesticCat cat where cat.name between 'A' and
'B'" );
+ parse( "from eg.DomesticCat cat where cat.name in ( 'Foo', 'Bar',
'Baz' )" );
+ parse( "from eg.DomesticCat cat where cat.name not between 'A' and
'B'" );
+ parse( "from eg.DomesticCat cat where cat.name not in ( 'Foo',
'Bar', 'Baz' )" );
+ parse( "from eg.Cat cat where cat.kittens.size > 0" );
+ parse( "from eg.Cat cat where size(cat.kittens) > 0" );
+// This is a little odd. I'm not sure whether 'current' is a keyword.
+// parse("from Calendar cal where cal.holidays.maxElement > current
date");
+// Using the token 'order' as both a keyword and an identifier works now, but
+// the second instance causes some problems because order is valid in the second
instance.
+// parse("from Order order where maxindex(order.items) > 100");
+// parse("from Order order where minelement(order.items) > 10000");
+ parse( "from Order ord where maxindex(ord.items) > 100" );
+ parse( "from Order ord where minelement(ord.items) > 10000" );
+
+ parse( "select mother from eg.Cat as mother, eg.Cat as kit\n"
+ + "where kit in elements(foo.kittens)" );
+ parse( "select p from eg.NameList list, eg.Person p\n"
+ + "where p.name = some elements(list.names)" );
+ parse( "from eg.Cat cat where exists elements(cat.kittens)" );
+ parse( "from eg.Player p where 3 > all elements(p.scores)" );
+ parse( "from eg.Show show where 'fizard' in indices(show.acts)" );
+
+ // Yet another example of the pathological 'order' token.
+// parse("from Order order where order.items[0].id = 1234");
+// parse("select person from Person person, Calendar calendar\n"
+// + "where calendar.holidays['national day'] =
person.birthDay\n"
+// + "and person.nationality.calendar = calendar");
+// parse("select item from Item item, Order order\n"
+// + "where order.items[ order.deliveredItemIndices[0] ] = item and order.id
= 11");
+// parse("select item from Item item, Order order\n"
+// + "where order.items[ maxindex(order.items) ] = item and order.id =
11");
+
+ parse( "from Order ord where ord.items[0].id = 1234" );
+ parse( "select person from Person person, Calendar calendar\n"
+ + "where calendar.holidays['national day'] = person.birthDay\n"
+ + "and person.nationality.calendar = calendar" );
+ parse( "select item from Item item, Order ord\n"
+ + "where ord.items[ ord.deliveredItemIndices[0] ] = item and ord.id = 11"
);
+ parse( "select item from Item item, Order ord\n"
+ + "where ord.items[ maxindex(ord.items) ] = item and ord.id = 11" );
+
+ parse( "select item from Item item, Order ord\n"
+ + "where ord.items[ size(ord.items) - 1 ] = item" );
+
+ parse( "from eg.DomesticCat cat where upper(cat.name) like 'FRI%'"
);
+
+ parse( "select cust from Product prod, Store store\n"
+ + "inner join store.customers cust\n"
+ + "where prod.name = 'widget'\n"
+ + "and store.location.name in ( 'Melbourne', 'Sydney' )\n"
+ + "and prod = all elements(cust.currentOrder.lineItems)" );
+
+ }
+
+ public void testDocoExamples99() throws Exception {
+ parse( "from eg.DomesticCat cat\n"
+ + "order by cat.name asc, cat.weight desc, cat.birthdate" );
+ }
+
+ public void testDocoExamples910() throws Exception {
+ parse( "select cat.color, sum(cat.weight), count(cat)\n"
+ + "from eg.Cat cat group by cat.color" );
+ parse( "select foo.id, avg( elements(foo.names) ), max( indices(foo.names)
)\n"
+ + "from eg.Foo foo group by foo.id" );
+ parse( "select cat.color, sum(cat.weight), count(cat)\n"
+ + "from eg.Cat cat group by cat.color\n"
+ + "having cat.color in (eg.Color.TABBY, eg.Color.BLACK)" );
+ parse( "select cat from eg.Cat cat join cat.kittens kitten\n"
+ + "group by cat having avg(kitten.weight) > 100\n"
+ + "order by count(kitten) asc, sum(kitten.weight) desc" );
+ }
+
+ public void testDocoExamples911() throws Exception {
+ parse( "from eg.Cat as fatcat where fatcat.weight > (\n"
+ + "select avg(cat.weight) from eg.DomesticCat cat)" );
+ parse( "from eg.DomesticCat as cat where cat.name = some (\n"
+ + "select name.nickName from eg.Name as name)\n" );
+ parse( "from eg.Cat as cat where not exists (\n"
+ + "from eg.Cat as mate where mate.mate = cat)" );
+ parse( "from eg.DomesticCat as cat where cat.name not in (\n"
+ + "select name.nickName from eg.Name as name)" );
+ }
+
+ public void testDocoExamples912() throws Exception {
+ parse( "select ord.id, sum(price.amount), count(item)\n"
+ + "from Order as ord join ord.lineItems as item\n"
+ + "join item.product as product, Catalog as catalog\n"
+ + "join catalog.prices as price\n"
+ + "where ord.paid = false\n"
+ + "and ord.customer = :customer\n"
+ + "and price.product = product\n"
+ + "and catalog.effectiveDate < sysdate\n"
+ + "and catalog.effectiveDate >= all (\n"
+ + "select cat.effectiveDate from Catalog as cat where cat.effectiveDate <
sysdate)\n"
+ + "group by ord\n"
+ + "having sum(price.amount) > :minAmount\n"
+ + "order by sum(price.amount) desc" );
+
+ parse( "select ord.id, sum(price.amount), count(item)\n"
+ + "from Order as ord join ord.lineItems as item join item.product as
product,\n"
+ + "Catalog as catalog join catalog.prices as price\n"
+ + "where ord.paid = false and ord.customer = :customer\n"
+ + "and price.product = product and catalog = :currentCatalog\n"
+ + "group by ord having sum(price.amount) > :minAmount\n"
+ + "order by sum(price.amount) desc" );
+
+ parse( "select count(payment), status.name \n"
+ + "from Payment as payment \n"
+ + " join payment.currentStatus as status\n"
+ + " join payment.statusChanges as statusChange\n"
+ + "where payment.status.name <> PaymentStatus.AWAITING_APPROVAL\n"
+ + " or (\n"
+ + " statusChange.timeStamp = ( \n"
+ + " select max(change.timeStamp) \n"
+ + " from PaymentStatusChange change \n"
+ + " where change.payment = payment\n"
+ + " )\n"
+ + " and statusChange.user <> :currentUser\n"
+ + " )\n"
+ + "group by status.name, status.sortOrder\n"
+ + "order by status.sortOrder" );
+ parse( "select count(payment), status.name \n"
+ + "from Payment as payment\n"
+ + " join payment.currentStatus as status\n"
+ + "where payment.status.name <> PaymentStatus.AWAITING_APPROVAL\n"
+ + " or payment.statusChanges[ maxIndex(payment.statusChanges) ].user <>
:currentUser\n"
+ + "group by status.name, status.sortOrder\n"
+ + "order by status.sortOrder" );
+ parse( "select account, payment\n"
+ + "from Account as account\n"
+ + " left outer join account.payments as payment\n"
+ + "where :currentUser in elements(account.holder.users)\n"
+ + " and PaymentStatus.UNPAID = isNull(payment.currentStatus.name,
PaymentStatus.UNPAID)\n"
+ + "order by account.type.sortOrder, account.accountNumber, payment.dueDate"
);
+ parse( "select account, payment\n"
+ + "from Account as account\n"
+ + " join account.holder.users as user\n"
+ + " left outer join account.payments as payment\n"
+ + "where :currentUser = user\n"
+ + " and PaymentStatus.UNPAID = isNull(payment.currentStatus.name,
PaymentStatus.UNPAID)\n"
+ + "order by account.type.sortOrder, account.accountNumber, payment.dueDate"
);
+ }
+
+ public void testExamples1() throws Exception {
+ parse( "select new org.hibernate.test.S(s.count, s.address)\n"
+ + "from s in class Simple" );
+ parse( "select s.name, sysdate, trunc(s.pay), round(s.pay) from s in class
Simple" );
+ parse( "select round(s.pay, 2) from s" );
+ parse( "select abs(round(s.pay)) from s in class Simple" );
+ parse( "select trunc(round(sysdate)) from s in class Simple" );
+ }
+
+ public void testArrayExpr() throws Exception {
+ parse( "from Order ord where ord.items[0].id = 1234" );
+ }
+
+ public void testMultipleActualParameters() throws Exception {
+ parse( "select round(s.pay, 2) from s" );
+ }
+
+ public void testMultipleFromClasses() throws Exception {
+ parse( "FROM eg.mypackage.Cat qat, com.toadstool.Foo f" );
+ parse( "FROM eg.mypackage.Cat qat, org.jabberwocky.Dipstick" );
+ }
+
+ public void testFromWithJoin() throws Exception {
+ parse( "FROM eg.mypackage.Cat qat, com.toadstool.Foo f join
net.sf.blurb.Blurb" );
+ parse( "FROM eg.mypackage.Cat qat left join com.multijoin.JoinORama ,
com.toadstool.Foo f join net.sf.blurb.Blurb" );
+ }
+
+ public void testSelect() throws Exception {
+ parse( "SELECT f FROM eg.mypackage.Cat qat, com.toadstool.Foo f join
net.sf.blurb.Blurb" );
+ parse( "SELECT DISTINCT bar FROM eg.mypackage.Cat qat left join
com.multijoin.JoinORama as bar, com.toadstool.Foo f join net.sf.blurb.Blurb" );
+ parse( "SELECT count(*) FROM eg.mypackage.Cat qat" );
+ parse( "SELECT avg(qat.weight) FROM eg.mypackage.Cat qat" );
+ }
+
+ public void testWhere() throws Exception {
+ parse( "FROM eg.mypackage.Cat qat where qat.name like '%fluffy%' or
qat.toes > 5" );
+ parse( "FROM eg.mypackage.Cat qat where not qat.name like '%fluffy%' or
qat.toes > 5" );
+ parse( "FROM eg.mypackage.Cat qat where not qat.name not like
'%fluffy%'" );
+ parse( "FROM eg.mypackage.Cat qat where qat.name in
('crater','bean','fluffy')" );
+ parse( "FROM eg.mypackage.Cat qat where qat.name not in
('crater','bean','fluffy')" );
+ parse( "from Animal an where sqrt(an.bodyWeight)/2 > 10" );
+ parse( "from Animal an where (an.bodyWeight > 10 and an.bodyWeight < 100) or
an.bodyWeight is null" );
+ }
+
+ public void testGroupBy() throws Exception {
+ parse( "FROM eg.mypackage.Cat qat group by qat.breed" );
+ parse( "FROM eg.mypackage.Cat qat group by qat.breed, qat.eyecolor" );
+ }
+
+ public void testOrderBy() throws Exception {
+ parse( "FROM eg.mypackage.Cat qat order by avg(qat.toes)" );
+ parse( "from Animal an order by sqrt(an.bodyWeight)/2" );
+ }
+
+ public void testDoubleLiteral() throws Exception {
+ parse( "from eg.Cat as tinycat where fatcat.weight < 3.1415" );
+ parse( "from eg.Cat as enormouscat where fatcat.weight > 3.1415e3" );
+ }
+
+ public void testComplexConstructor() throws Exception {
+ parse( "select new Foo(count(bar)) from bar" );
+ parse( "select new Foo(count(bar),(select count(*) from doofus d where d.gob =
'fat' )) from bar" );
+ }
+
+
+ public void testInNotIn() throws Exception {
+ parse( "from foo where foo.bar in ('a' , 'b', 'c')"
);
+ parse( "from foo where foo.bar not in ('a' , 'b',
'c')" );
+ }
+
+ public void testOperatorPrecedence() throws Exception {
+ parse( "from foo where foo.bar = 123 + foo.baz * foo.not" );
+ parse( "from foo where foo.bar like 'testzzz' || foo.baz or foo.bar in
('duh', 'gob')" );
+ }
+
+ /**
+ * Tests HQL generated by the other unit tests.
+ *
+ * @throws Exception if the HQL could not be parsed.
+ */
+ public void testUnitTestHql() throws Exception {
+ parse( "select foo from foo in class org.hibernate.test.Foo, fee in class
org.hibernate.test.Fee where foo.dependent = fee order by foo.string desc,
foo.component.count asc, fee.id" );
+ parse( "select foo.foo, foo.dependent from foo in class org.hibernate.test.Foo
order by foo.foo.string desc, foo.component.count asc, foo.dependent.id" );
+ parse( "select foo from foo in class org.hibernate.test.Foo order by
foo.dependent.id, foo.dependent.fi" );
+ parse( "SELECT one FROM one IN CLASS org.hibernate.test.One ORDER BY one.value
ASC" );
+ parse( "SELECT many.one FROM many IN CLASS org.hibernate.test.Many ORDER BY
many.one.value ASC, many.one.id" );
+ parse( "select foo.id from org.hibernate.test.Foo foo where foo.joinedProp =
'foo'" );
+ parse( "from org.hibernate.test.Foo foo inner join fetch foo.foo" );
+ parse( "from org.hibernate.test.Baz baz left outer join fetch
baz.fooToGlarch" );
+ parse( "select foo.foo.foo.string from foo in class org.hibernate.test.Foo where
foo.foo = 'bar'" );
+ parse( "select foo.foo.foo.foo.string from foo in class org.hibernate.test.Foo
where foo.foo.foo = 'bar'" );
+ parse( "select foo.foo.foo.string from foo in class org.hibernate.test.Foo where
foo.foo.foo.foo.string = 'bar'" );
+ parse( "select foo.string from foo in class org.hibernate.test.Foo where
foo.foo.foo = 'bar' and foo.foo.foo.foo = 'baz'" );
+ parse( "select foo.string from foo in class org.hibernate.test.Foo where
foo.foo.foo.foo.string = 'a' and foo.foo.string = 'b'" );
+ parse( "from org.hibernate.test.Foo as foo where foo.component.glarch.name is not
null" );
+ parse( "from org.hibernate.test.Foo as foo left outer join foo.component.glarch as
glarch where glarch.name = 'foo'" );
+ parse( "from org.hibernate.test.Foo" );
+ parse( "from org.hibernate.test.Foo foo left outer join foo.foo" );
+ parse( "from org.hibernate.test.Foo, org.hibernate.test.Bar" );
+ parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch,
org.hibernate.test.Bar bar join bar.foo" );
+ parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch join
baz.fooSet" );
+ parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch join fetch
baz.fooSet foo left join fetch foo.foo" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.string='osama bin
laden' and foo.boolean = true order by foo.string asc, foo.component.count desc"
);
+ parse( "from foo in class org.hibernate.test.Foo where foo.string='osama bin
laden' order by foo.string asc, foo.component.count desc" );
+ parse( "select foo.foo from foo in class org.hibernate.test.Foo" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.component.count is null
order by foo.component.count" );
+ parse( "from foo in class org.hibernate.test.Foo where
foo.component.name='foo'" );
+ parse( "select distinct foo.component.name, foo.component.name from foo in class
org.hibernate.test.Foo where foo.component.name='foo'" );
+ parse( "select distinct foo.component.name, foo.id from foo in class
org.hibernate.test.Foo where foo.component.name='foo'" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.id=?" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.key=?" );
+ parse( "select foo.foo from foo in class org.hibernate.test.Foo where
foo.string='fizard'" );
+ parse( "from foo in class org.hibernate.test.Foo where
foo.component.subcomponent.name='bar'" );
+ parse( "select foo.foo from foo in class org.hibernate.test.Foo where
foo.foo.id=?" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.foo = ?" );
+ parse( "from bar in class org.hibernate.test.Bar where bar.string='a
string' or bar.string='a string'" );
+ parse( "select foo.component.name, elements(foo.component.importantDates) from foo
in class org.hibernate.test.Foo where foo.foo.id=?" );
+ parse( "select max(elements(foo.component.importantDates)) from foo in class
org.hibernate.test.Foo group by foo.id" );
+ parse( "select foo.foo.foo.foo from foo in class org.hibernate.test.Foo, foo2 in
class org.hibernate.test.Foo where foo = foo2.foo and not not ( not
foo.string='fizard' ) and foo2.string between 'a' and (foo.foo.string) and
( foo2.string in ( 'fiz', 'blah') or 1=1 )" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.string='from
BoogieDown -tinsel town =!@#$^&*())'" );
+ parse( "from foo in class org.hibernate.test.Foo where not
foo.string='foo''bar'" ); // Added quote quote is an escape
+ parse( "from foo in class org.hibernate.test.Foo where foo.component.glarch.next
is null" );
+ parse( " from bar in class org.hibernate.test.Bar where bar.baz.count=667 and
bar.baz.count!=123 and not bar.baz.name='1-E-1'" );
+ parse( " from i in class org.hibernate.test.Bar where
i.baz.name='Bazza'" );
+ parse( "select count(distinct foo.foo) from foo in class
org.hibernate.test.Foo" );
+ parse( "select count(foo.foo.boolean) from foo in class
org.hibernate.test.Foo" );
+ parse( "select count(*),
foo.int from foo in class org.hibernate.test.Foo group by
foo.int" );
+ parse( "select sum(foo.foo.int) from foo in class org.hibernate.test.Foo" );
+ parse( "select count(foo) from foo in class org.hibernate.test.Foo where
foo.id=?" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.boolean = ?" );
+ parse( "select new Foo(fo.x) from org.hibernate.test.Fo fo" );
+ parse( "select new Foo(fo.integer) from org.hibernate.test.Foo fo" );
+ parse( "select new Foo(fo.x) from org.hibernate.test.Foo fo" );
+ parse( "select foo.long, foo.component.name, foo, foo.foo from foo in class
org.hibernate.test.Foo" );
+ parse( "select avg(foo.float), max(foo.component.name), count(distinct foo.id)
from foo in class org.hibernate.test.Foo" );
+ parse( "select foo.long, foo.component, foo, foo.foo from foo in class
org.hibernate.test.Foo" );
+ parse( "from o in class org.hibernate.test.MoreStuff" );
+ parse( "from o in class org.hibernate.test.Many" );
+ parse( "from o in class org.hibernate.test.Fee" );
+ parse( "from o in class org.hibernate.test.Qux" );
+ parse( "from o in class org.hibernate.test.Y" );
+ parse( "from o in class org.hibernate.test.Fumm" );
+ parse( "from o in class org.hibernate.test.X" );
+ parse( "from o in class org.hibernate.test.Simple" );
+ parse( "from o in class org.hibernate.test.Location" );
+ parse( "from o in class org.hibernate.test.Holder" );
+ parse( "from o in class org.hibernate.test.Part" );
+ parse( "from o in class org.hibernate.test.Baz" );
+ parse( "from o in class org.hibernate.test.Vetoer" );
+ parse( "from o in class org.hibernate.test.Sortable" );
+ parse( "from o in class org.hibernate.test.Contained" );
+ parse( "from o in class org.hibernate.test.Stuff" );
+ parse( "from o in class org.hibernate.test.Immutable" );
+ parse( "from o in class org.hibernate.test.Container" );
+ parse( "from o in class org.hibernate.test.X$XX" );
+ parse( "from o in class org.hibernate.test.One" );
+ parse( "from o in class org.hibernate.test.Foo" );
+ parse( "from o in class org.hibernate.test.Fo" );
+ parse( "from o in class org.hibernate.test.Glarch" );
+ parse( "from o in class org.hibernate.test.Fum" );
+ parse( "from n in class org.hibernate.test.Holder" );
+ parse( "from n in class org.hibernate.test.Baz" );
+ parse( "from n in class org.hibernate.test.Bar" );
+ parse( "from n in class org.hibernate.test.Glarch" );
+ parse( "from n in class org.hibernate.test.Holder where n.name is not null"
);
+ parse( "from n in class org.hibernate.test.Baz where n.name is not null" );
+ parse( "from n in class org.hibernate.test.Bar where n.name is not null" );
+ parse( "from n in class org.hibernate.test.Glarch where n.name is not null"
);
+ parse( "from n in class org.hibernate.test.Holder" );
+ parse( "from n in class org.hibernate.test.Baz" );
+ parse( "from n in class org.hibernate.test.Bar" );
+ parse( "from n in class org.hibernate.test.Glarch" );
+ parse( "from n0 in class org.hibernate.test.Holder, n1 in class
org.hibernate.test.Holder where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Baz, n1 in class
org.hibernate.test.Holder where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Bar, n1 in class
org.hibernate.test.Holder where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Glarch, n1 in class
org.hibernate.test.Holder where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Holder, n1 in class
org.hibernate.test.Baz where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Baz, n1 in class
org.hibernate.test.Baz where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Bar, n1 in class
org.hibernate.test.Baz where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Glarch, n1 in class
org.hibernate.test.Baz where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Holder, n1 in class
org.hibernate.test.Bar where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Baz, n1 in class
org.hibernate.test.Bar where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Bar, n1 in class
org.hibernate.test.Bar where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Glarch, n1 in class
org.hibernate.test.Bar where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Holder, n1 in class
org.hibernate.test.Glarch where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Baz, n1 in class
org.hibernate.test.Glarch where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Bar, n1 in class
org.hibernate.test.Glarch where n0.name = n1.name" );
+ parse( "from n0 in class org.hibernate.test.Glarch, n1 in class
org.hibernate.test.Glarch where n0.name = n1.name" );
+ parse( "from n in class org.hibernate.test.Holder where n.name = :name" );
+ parse( "from o in class org.hibernate.test.MoreStuff" );
+ parse( "from o in class org.hibernate.test.Many" );
+ parse( "from o in class org.hibernate.test.Fee" );
+ parse( "from o in class org.hibernate.test.Qux" );
+ parse( "from o in class org.hibernate.test.Y" );
+ parse( "from o in class org.hibernate.test.Fumm" );
+ parse( "from o in class org.hibernate.test.X" );
+ parse( "from o in class org.hibernate.test.Simple" );
+ parse( "from o in class org.hibernate.test.Location" );
+ parse( "from o in class org.hibernate.test.Holder" );
+ parse( "from o in class org.hibernate.test.Part" );
+ parse( "from o in class org.hibernate.test.Baz" );
+ parse( "from o in class org.hibernate.test.Vetoer" );
+ parse( "from o in class org.hibernate.test.Sortable" );
+ parse( "from o in class org.hibernate.test.Contained" );
+ parse( "from o in class org.hibernate.test.Stuff" );
+ parse( "from o in class org.hibernate.test.Immutable" );
+ parse( "from o in class org.hibernate.test.Container" );
+ parse( "from o in class org.hibernate.test.X$XX" );
+ parse( "from o in class org.hibernate.test.One" );
+ parse( "from o in class org.hibernate.test.Foo" );
+ parse( "from o in class org.hibernate.test.Fo" );
+ parse( "from o in class org.hibernate.test.Glarch" );
+ parse( "from o in class org.hibernate.test.Fum" );
+ parse( "select baz.code, min(baz.count) from baz in class org.hibernate.test.Baz
group by baz.code" );
+ parse( "selecT baz from baz in class org.hibernate.test.Baz where
baz.stringDateMap['foo'] is not null or baz.stringDateMap['bar'] = ?"
);
+ parse( "select baz from baz in class org.hibernate.test.Baz where
baz.stringDateMap['now'] is not null" );
+ parse( "select baz from baz in class org.hibernate.test.Baz where
baz.stringDateMap['now'] is not null and baz.stringDateMap['big bang']
< baz.stringDateMap['now']" );
+ parse( "select index(date) from org.hibernate.test.Baz baz join baz.stringDateMap
as date" );
+ parse( "select index(date) from org.hibernate.test.Baz baz join baz.stringDateMap
date" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.integer not between 1
and 5 and foo.string not in ('cde', 'abc') and foo.string is not null and
foo.integer<=3" );
+ parse( "from org.hibernate.test.Baz baz inner join
baz.collectionComponent.nested.foos foo where foo.string is null" );
+ parse( "from org.hibernate.test.Baz baz inner join baz.fooSet where '1' in
(from baz.fooSet foo where foo.string is not null)" );
+ parse( "from org.hibernate.test.Baz baz where 'a' in
elements(baz.collectionComponent.nested.foos) and 1.0 in
elements(baz.collectionComponent.nested.floats)" );
+ parse( "from org.hibernate.test.Foo foo join foo.foo where foo.foo in
('1','2','3')" );
+ parse( "select foo.foo from org.hibernate.test.Foo foo where foo.foo in
('1','2','3')" );
+ parse( "select foo.foo.string from org.hibernate.test.Foo foo where foo.foo in
('1','2','3')" );
+ parse( "select foo.foo.string from org.hibernate.test.Foo foo where foo.foo.string
in ('1','2','3')" );
+ parse( "select foo.foo.long from org.hibernate.test.Foo foo where foo.foo.string
in ('1','2','3')" );
+ parse( "select count(*) from org.hibernate.test.Foo foo where foo.foo.string in
('1','2','3') or foo.foo.long in (1,2,3)" );
+ parse( "select count(*) from org.hibernate.test.Foo foo where foo.foo.string in
('1','2','3') group by foo.foo.long" );
+ parse( "from org.hibernate.test.Foo foo1 left join foo1.foo foo2 left join
foo2.foo where foo1.string is not null" );
+ parse( "from org.hibernate.test.Foo foo1 left join foo1.foo.foo where foo1.string
is not null" );
+ parse( "from org.hibernate.test.Foo foo1 left join foo1.foo foo2 left join
foo1.foo.foo foo3 where foo1.string is not null" );
+ parse( "select foo.formula from org.hibernate.test.Foo foo where foo.formula >
0" );
+ parse( "from org.hibernate.test.Foo as foo join foo.foo as foo2 where foo2.id
>'a' or foo2.id <'a'" );
+ parse( "from org.hibernate.test.Holder" );
+ parse( "from org.hibernate.test.Baz baz left outer join fetch baz.manyToAny"
);
+ parse( "from org.hibernate.test.Baz baz join baz.manyToAny" );
+ parse( "select baz from org.hibernate.test.Baz baz join baz.manyToAny a where
index(a) = 0" );
+ parse( "select bar from org.hibernate.test.Bar bar where
bar.baz.stringDateMap['now'] is not null" );
+ parse( "select bar from org.hibernate.test.Bar bar join bar.baaz b where
b.stringDateMap['big bang'] < b.stringDateMap['now'] and
b.stringDateMap['now'] is not null" );
+ parse( "select bar from org.hibernate.test.Bar bar where
bar.baz.stringDateMap['big bang'] < bar.baz.stringDateMap['now'] and
bar.baz.stringDateMap['now'] is not null" );
+ parse( "select foo.string, foo.component, foo.id from org.hibernate.test.Bar
foo" );
+ parse( "select elements(baz.components) from org.hibernate.test.Baz baz" );
+ parse( "select bc.name from org.hibernate.test.Baz baz join baz.components
bc" );
+ parse( "from org.hibernate.test.Foo foo where foo.integer < 10 order by
foo.string" );
+ parse( "from org.hibernate.test.Fee" );
+ parse( "from org.hibernate.test.Holder h join h.otherHolder oh where
h.otherHolder.name = 'bar'" );
+ parse( "from org.hibernate.test.Baz baz join baz.fooSet foo join foo.foo.foo foo2
where foo2.string = 'foo'" );
+ parse( "from org.hibernate.test.Baz baz join baz.fooArray foo join foo.foo.foo
foo2 where foo2.string = 'foo'" );
+ parse( "from org.hibernate.test.Baz baz join baz.stringDateMap date where
index(date) = 'foo'" );
+ parse( "from org.hibernate.test.Baz baz join baz.topGlarchez g where index(g) =
'A'" );
+ parse( "select index(g) from org.hibernate.test.Baz baz join baz.topGlarchez
g" );
+ parse( "from org.hibernate.test.Baz baz left join baz.stringSet" );
+ parse( "from org.hibernate.test.Baz baz join baz.stringSet str where
str='foo'" );
+ parse( "from org.hibernate.test.Baz baz left join fetch baz.stringSet" );
+ parse( "from org.hibernate.test.Baz baz join baz.stringSet string where
string='foo'" );
+ parse( "from org.hibernate.test.Baz baz inner join baz.components comp where
comp.name='foo'" );
+ parse( "from org.hibernate.test.Glarch g inner join g.fooComponents comp where
comp.fee is not null" );
+ parse( "from org.hibernate.test.Glarch g inner join g.fooComponents comp join
comp.fee fee where fee.count > 0" );
+ parse( "from org.hibernate.test.Glarch g inner join g.fooComponents comp where
comp.fee.count is not null" );
+ parse( "from org.hibernate.test.Baz baz left join fetch baz.fooBag" );
+ parse( "from org.hibernate.test.Glarch" );
+ parse( "from org.hibernate.test.Fee" );
+ parse( "from org.hibernate.test.Baz baz left join fetch baz.sortablez order by
baz.name asc" );
+ parse( "from org.hibernate.test.Baz baz order by baz.name asc" );
+ parse( "from org.hibernate.test.Foo foo, org.hibernate.test.Baz baz left join
fetch baz.fees" );
+ parse( "from org.hibernate.test.Foo foo, org.hibernate.test.Bar bar" );
+ parse( "from org.hibernate.test.Foo foo" );
+ parse( "from org.hibernate.test.Foo foo, org.hibernate.test.Bar bar,
org.hibernate.test.Bar bar2" );
+ parse( "from org.hibernate.test.X x" );
+ parse( "from org.hibernate.test.Foo foo" );
+ parse( "select distinct foo from org.hibernate.test.Foo foo" );
+ parse( "from org.hibernate.test.Glarch g where g.multiple.glarch=g and
g.multiple.count=12" );
+ parse( "from org.hibernate.test.Bar bar left join bar.baz baz left join
baz.cascadingBars b where bar.name like 'Bar %'" );
+ parse( "select bar, b from org.hibernate.test.Bar bar left join bar.baz baz left
join baz.cascadingBars b where bar.name like 'Bar%'" );
+ parse( "select bar, b from org.hibernate.test.Bar bar left join bar.baz baz left
join baz.cascadingBars b where ( bar.name in (:nameList0_, :nameList1_, :nameList2_) or
bar.name in (:nameList0_, :nameList1_, :nameList2_) ) and bar.string = :stringVal"
);
+ parse( "select bar, b from org.hibernate.test.Bar bar inner join bar.baz baz inner
join baz.cascadingBars b where bar.name like 'Bar%'" );
+ parse( "select bar, b from org.hibernate.test.Bar bar left join bar.baz baz left
join baz.cascadingBars b where bar.name like :name and b.name like :name" );
+ parse( "select bar from org.hibernate.test.Bar as bar where bar.x > ? or
bar.short = 1 or bar.string = 'ff ? bb'" );
+ parse( "select bar from org.hibernate.test.Bar as bar where bar.string = ' ?
' or bar.string = '?'" );
+ parse( "from org.hibernate.test.Baz baz, baz.fooArray foo" );
+ parse( "from s in class org.hibernate.test.Stuff where s.foo.id = ? and s.id.id =
? and s.moreStuff.id.intId = ? and s.moreStuff.id.stringId = ?" );
+ parse( "from s in class org.hibernate.test.Stuff where s.foo.id = ? and s.id.id =
? and s.moreStuff.name = ?" );
+ parse( "from s in class org.hibernate.test.Stuff where s.foo.string is not
null" );
+ parse( "from s in class org.hibernate.test.Stuff where s.foo > '0'
order by s.foo" );
+ parse( "from ms in class org.hibernate.test.MoreStuff" );
+ parse( "from foo in class org.hibernate.test.Foo" );
+ parse( "from fee in class org.hibernate.test.Fee" );
+ parse( "select new Result(foo.string, foo.long, foo.integer) from foo in class
org.hibernate.test.Foo" );
+ parse( "select new Result( baz.name, foo.long, count(elements(baz.fooArray)) )
from org.hibernate.test.Baz baz join baz.fooArray foo group by baz.name, foo.long"
);
+ parse( "select new Result( baz.name, max(foo.long), count(foo) ) from
org.hibernate.test.Baz baz join baz.fooArray foo group by baz.name" );
+ parse( "select max( elements(bar.baz.fooArray) ) from org.hibernate.test.Bar as
bar" );
+ parse( "from org.hibernate.test.Baz baz left join baz.fooToGlarch join fetch
baz.fooArray foo left join fetch foo.foo" );
+ parse( "select baz.name from org.hibernate.test.Bar bar inner join bar.baz baz
inner join baz.fooSet foo where baz.name = bar.string" );
+ parse( "SELECT baz.name FROM org.hibernate.test.Bar AS bar INNER JOIN bar.baz AS
baz INNER JOIN baz.fooSet AS foo WHERE baz.name = bar.string" );
+ parse( "select baz.name from org.hibernate.test.Bar bar join bar.baz baz left
outer join baz.fooSet foo where baz.name = bar.string" );
+ parse( "select baz.name from org.hibernate.test.Bar bar, bar.baz baz, baz.fooSet
foo where baz.name = bar.string" );
+ parse( "SELECT baz.name FROM org.hibernate.test.Bar AS bar, bar.baz AS baz,
baz.fooSet AS foo WHERE baz.name = bar.string" );
+ parse( "select baz.name from org.hibernate.test.Bar bar left join bar.baz baz left
join baz.fooSet foo where baz.name = bar.string" );
+ parse( "select foo.string from org.hibernate.test.Bar bar left join bar.baz.fooSet
foo where bar.string = foo.string" );
+ parse( "select baz.name from org.hibernate.test.Bar bar left join bar.baz baz left
join baz.fooArray foo where baz.name = bar.string" );
+ parse( "select foo.string from org.hibernate.test.Bar bar left join
bar.baz.fooArray foo where bar.string = foo.string" );
+ parse( "select foo from bar in class org.hibernate.test.Bar inner join bar.baz as
baz inner join baz.fooSet as foo" );
+ parse( "select foo from bar in class org.hibernate.test.Bar inner join
bar.baz.fooSet as foo" );
+ parse( "select foo from bar in class org.hibernate.test.Bar, bar.baz as baz,
baz.fooSet as foo" );
+ parse( "select foo from bar in class org.hibernate.test.Bar, bar.baz.fooSet as
foo" );
+ parse( "from org.hibernate.test.Bar bar join bar.baz.fooArray foo" );
+ parse( "from bar in class org.hibernate.test.Bar, foo in elements(
bar.baz.fooArray )" );
+ parse( "select one.id, elements(one.manies) from one in class
org.hibernate.test.One" );
+ parse( "select max( elements(one.manies) ) from one in class
org.hibernate.test.One" );
+ parse( "select one, elements(one.manies) from one in class
org.hibernate.test.One" );
+ parse( "select one, max(elements(one.manies)) from one in class
org.hibernate.test.One group by one" );
+ parse( "select elements(baz.fooArray) from baz in class org.hibernate.test.Baz
where baz.id=?" );
+ parse( "select elements(baz.fooArray) from baz in class org.hibernate.test.Baz
where baz.id=?" );
+ parse( "select indices(baz.fooArray) from baz in class org.hibernate.test.Baz
where baz.id=?" );
+ parse( "select baz, max(elements(baz.timeArray)) from baz in class
org.hibernate.test.Baz group by baz" );
+ parse( "select baz, baz.stringSet.size, count(distinct elements(baz.stringSet)),
max(elements(baz.stringSet)) from baz in class org.hibernate.test.Baz group by baz"
);
+ parse( "select max( elements(baz.timeArray) ) from baz in class
org.hibernate.test.Baz where baz.id=?" );
+ parse( "select max(elements(baz.stringSet)) from baz in class
org.hibernate.test.Baz where baz.id=?" );
+ parse( "select size(baz.stringSet) from baz in class org.hibernate.test.Baz where
baz.id=?" );
+ parse( "from org.hibernate.test.Foo foo where foo.component.glarch.id is not
null" );
+ parse( "from baz in class org.hibernate.test.Baz" );
+ parse( "select elements(baz.stringArray) from baz in class
org.hibernate.test.Baz" );
+ parse( "from foo in class org.hibernate.test.Foo" );
+ parse( "select elements(baz.stringList) from baz in class
org.hibernate.test.Baz" );
+ parse( "select count(*) from org.hibernate.test.Bar" );
+ parse( "select count(*) from b in class org.hibernate.test.Bar" );
+ parse( "from g in class org.hibernate.test.Glarch" );
+ parse( "select baz, baz from baz in class org.hibernate.test.Baz" );
+ parse( "select baz from baz in class org.hibernate.test.Baz order by baz" );
+ parse( "from bar in class org.hibernate.test.Bar" );
+ parse( "from g in class org.hibernate.test.Glarch" );
+ parse( "from f in class org.hibernate.test.Foo" );
+ parse( "from o in class org.hibernate.test.One" );
+ parse( "from q in class org.hibernate.test.Qux" );
+ parse( "select foo from foo in class org.hibernate.test.Foo where
foo.string='foo bar'" );
+ parse( "from foo in class org.hibernate.test.Foo order by foo.string,
foo.date" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.class='B'"
);
+ parse( "from foo in class org.hibernate.test.Foo where foo.class=Bar" );
+ parse( "select bar from bar in class org.hibernate.test.Bar, foo in class
org.hibernate.test.Foo where bar.string = foo.string and not bar=foo" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.string='foo
bar'" );
+ parse( "select foo from foo in class org.hibernate.test.Foo" );
+ parse( "from bar in class org.hibernate.test.Bar where bar.barString='bar
bar'" );
+ parse( "from t in class org.hibernate.test.Trivial" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.date = ?" );
+ parse( "from o in class org.hibernate.test.MoreStuff" );
+ parse( "from o in class org.hibernate.test.Many" );
+ parse( "from o in class org.hibernate.test.Fee" );
+ parse( "from o in class org.hibernate.test.Qux" );
+ parse( "from o in class org.hibernate.test.Y" );
+ parse( "from o in class org.hibernate.test.Fumm" );
+ parse( "from o in class org.hibernate.test.X" );
+ parse( "from o in class org.hibernate.test.Simple" );
+ parse( "from o in class org.hibernate.test.Location" );
+ parse( "from o in class org.hibernate.test.Holder" );
+ parse( "from o in class org.hibernate.test.Part" );
+ parse( "from o in class org.hibernate.test.Baz" );
+ parse( "from o in class org.hibernate.test.Vetoer" );
+ parse( "from o in class org.hibernate.test.Sortable" );
+ parse( "from o in class org.hibernate.test.Contained" );
+ parse( "from o in class org.hibernate.test.Stuff" );
+ parse( "from o in class org.hibernate.test.Immutable" );
+ parse( "from o in class org.hibernate.test.Container" );
+ parse( "from o in class org.hibernate.test.X$XX" );
+ parse( "from o in class org.hibernate.test.One" );
+ parse( "from o in class org.hibernate.test.Foo" );
+ parse( "from o in class org.hibernate.test.Fo" );
+ parse( "from o in class org.hibernate.test.Glarch" );
+ parse( "from o in class org.hibernate.test.Fum" );
+ parse( "from q in class org.hibernate.test.Qux where q.stuff is null" );
+ parse( "from q in class org.hibernate.test.Qux where q.stuff=?" );
+ parse( "from q in class org.hibernate.test.Qux" );
+ parse( "from g in class org.hibernate.test.Glarch where g.version=2" );
+ parse( "from g in class org.hibernate.test.Glarch where g.next is not null"
);
+ parse( "from g in class org.hibernate.test.Glarch order by g.order asc" );
+ parse( "from foo in class org.hibernate.test.Foo order by foo.string asc" );
+ parse( "select parent, child from parent in class org.hibernate.test.Foo, child in
class org.hibernate.test.Foo where parent.foo = child" );
+ parse( "select count(distinct child.id), count(distinct parent.id) from parent in
class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo =
child" );
+ parse( "select child.id, parent.id, child.long from parent in class
org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo =
child" );
+ parse( "select child.id, parent.id, child.long, child, parent.foo from parent in
class org.hibernate.test.Foo, child in class org.hibernate.test.Foo where parent.foo =
child" );
+ parse( "select parent, child from parent in class org.hibernate.test.Foo, child in
class org.hibernate.test.Foo where parent.foo = child and parent.string='a
string'" );
+ parse( "from fee in class org.hibernate.test.Fee" );
+ parse( "from org.hibernate.test.Foo foo where foo.custom.s1 = 'one'"
);
+ parse( "from im in class org.hibernate.test.Immutable where im = ?" );
+ parse( "from foo in class org.hibernate.test.Foo" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.char='X'"
);
+ parse( "select elements(baz.stringArray) from baz in class
org.hibernate.test.Baz" );
+ parse( "select distinct elements(baz.stringArray) from baz in class
org.hibernate.test.Baz" );
+ parse( "select elements(baz.fooArray) from baz in class
org.hibernate.test.Baz" );
+ parse( "from foo in class org.hibernate.test.Fo" );
+ parse( "from foo in class org.hibernate.test.Foo where
foo.dependent.qux.foo.string = 'foo2'" );
+ parse( "from org.hibernate.test.Bar bar where bar.object.id = ? and
bar.object.class = ?" );
+ parse( "select one from org.hibernate.test.One one, org.hibernate.test.Bar bar
where bar.object.id = one.id and bar.object.class = 'O'" );
+ parse( "from l in class org.hibernate.test.Location where l.countryCode =
'AU' and l.description='foo bar'" );
+ parse( "from org.hibernate.test.Bar bar" );
+ parse( "From org.hibernate.test.Bar bar" );
+ parse( "From org.hibernate.test.Foo foo" );
+ parse( "from o in class org.hibernate.test.Baz" );
+ parse( "from o in class org.hibernate.test.Foo" );
+ parse( "from f in class org.hibernate.test.Foo" );
+ parse( "select fum.id from fum in class org.hibernate.test.Fum where not
fum.fum='FRIEND'" );
+ parse( "select fum.id from fum in class org.hibernate.test.Fum where not
fum.fum='FRIEND'" );
+ parse( "from fum in class org.hibernate.test.Fum where not
fum.fum='FRIEND'" );
+ parse( "from fo in class org.hibernate.test.Fo where fo.id.string like 'an
instance of fo'" );
+ parse( "from org.hibernate.test.Inner" );
+ parse( "from org.hibernate.test.Outer o where o.id.detailId = ?" );
+ parse( "from org.hibernate.test.Outer o where o.id.master.id.sup.dudu is not
null" );
+ parse( "from org.hibernate.test.Outer o where o.id.master.id.sup.id.akey is not
null" );
+ parse( "select o.id.master.id.sup.dudu from org.hibernate.test.Outer o where
o.id.master.id.sup.dudu is not null" );
+ parse( "select o.id.master.id.sup.id.akey from org.hibernate.test.Outer o where
o.id.master.id.sup.id.akey is not null" );
+ parse( "from org.hibernate.test.Outer o where o.id.master.bla = ''"
);
+ parse( "from org.hibernate.test.Outer o where o.id.master.id.one =
''" );
+ parse( "from org.hibernate.test.Inner inn where inn.id.bkey is not null and
inn.backOut.id.master.id.sup.id.akey > 'a'" );
+ parse( "from org.hibernate.test.Outer as o left join o.id.master m left join
m.id.sup where o.bubu is not null" );
+ parse( "from org.hibernate.test.Outer as o left join o.id.master.id.sup s where
o.bubu is not null" );
+ parse( "from org.hibernate.test.Outer as o left join o.id.master m left join
o.id.master.id.sup s where o.bubu is not null" );
+ parse( "select fum1.fo from fum1 in class org.hibernate.test.Fum where fum1.fo.fum
is not null" );
+ parse( "from fum1 in class org.hibernate.test.Fum where fum1.fo.fum is not null
order by fum1.fo.fum" );
+ parse( "select elements(fum1.friends) from fum1 in class
org.hibernate.test.Fum" );
+ parse( "from fum1 in class org.hibernate.test.Fum, fr in elements( fum1.friends
)" );
+ parse( "select new Jay(eye) from org.hibernate.test.Eye eye" );
+ parse( "from org.hibernate.test.Category cat where cat.name='new
foo'" );
+ parse( "from org.hibernate.test.Category cat where cat.name='new
sub'" );
+ parse( "from org.hibernate.test.Up up order by up.id2 asc" );
+ parse( "from org.hibernate.test.Down down" );
+ parse( "from org.hibernate.test.Up up" );
+ parse( "from m in class org.hibernate.test.Master" );
+ parse( "from s in class org.hibernate.test.Several" );
+ parse( "from s in class org.hibernate.test.Single" );
+ parse( "\n" +
+ " from d in class \n" +
+ " org.hibernate.test.Detail\n" +
+ " " );
+ parse( "from c in class org.hibernate.test.Category where c.name =
org.hibernate.test.Category.ROOT_CATEGORY" );
+ parse( "select c from c in class org.hibernate.test.Container, s in class
org.hibernate.test.Simple where c.oneToMany[2] = s" );
+ parse( "select c from c in class org.hibernate.test.Container, s in class
org.hibernate.test.Simple where c.manyToMany[2] = s" );
+ parse( "select c from c in class org.hibernate.test.Container, s in class
org.hibernate.test.Simple where s = c.oneToMany[2]" );
+ parse( "select c from c in class org.hibernate.test.Container, s in class
org.hibernate.test.Simple where s = c.manyToMany[2]" );
+ parse( "select c from c in class org.hibernate.test.Container where
c.oneToMany[0].name = 's'" );
+ parse( "select c from c in class org.hibernate.test.Container where
c.manyToMany[0].name = 's'" );
+ parse( "select c from c in class org.hibernate.test.Container where 's' =
c.oneToMany[2 - 2].name" );
+ parse( "select c from c in class org.hibernate.test.Container where 's' =
c.manyToMany[(3+1)/4-1].name" );
+ parse( "select c from c in class org.hibernate.test.Container where c.manyToMany[
maxindex(c.manyToMany) ].count = 2" );
+ parse( "select c from c in class org.hibernate.test.Container where c.oneToMany[
c.manyToMany[0].count ].name = 's'" );
+ parse( "select c from org.hibernate.test.Container c where c.manyToMany[
c.oneToMany[0].count ].name = 's'" );
+ parse( "select count(comp.name) from org.hibernate.test.Container c join
c.components comp" );
+ parse( "from org.hibernate.test.Parent p left join fetch p.child" );
+ parse( "from org.hibernate.test.Parent p join p.child c where c.x > 0" );
+ parse( "from org.hibernate.test.Child c join c.parent p where p.x > 0" );
+ parse( "from org.hibernate.test.Child" );
+ parse( "from org.hibernate.test.MoreStuff" );
+ parse( "from org.hibernate.test.Many" );
+ parse( "from org.hibernate.test.Fee" );
+ parse( "from org.hibernate.test.Qux" );
+ parse( "from org.hibernate.test.Fumm" );
+ parse( "from org.hibernate.test.Parent" );
+ parse( "from org.hibernate.test.Simple" );
+ parse( "from org.hibernate.test.Holder" );
+ parse( "from org.hibernate.test.Part" );
+ parse( "from org.hibernate.test.Baz" );
+ parse( "from org.hibernate.test.Vetoer" );
+ parse( "from org.hibernate.test.Sortable" );
+ parse( "from org.hibernate.test.Contained" );
+ parse( "from org.hibernate.test.Circular" );
+ parse( "from org.hibernate.test.Stuff" );
+ parse( "from org.hibernate.test.Immutable" );
+ parse( "from org.hibernate.test.Container" );
+ parse( "from org.hibernate.test.One" );
+ parse( "from org.hibernate.test.Foo" );
+ parse( "from org.hibernate.test.Fo" );
+ parse( "from org.hibernate.test.Glarch" );
+ parse( "from org.hibernate.test.Fum" );
+ parse( "from org.hibernate.test.Glarch g" );
+ parse( "from org.hibernate.test.Part" );
+ parse( "from org.hibernate.test.Baz baz join baz.parts" );
+ parse( "from c in class org.hibernate.test.Child where c.parent.count=66" );
+ parse( "from org.hibernate.test.Parent p join p.child c where p.count=66" );
+ parse( "select c, c.parent from c in class org.hibernate.test.Child order by
c.parent.count" );
+ parse( "select c, c.parent from c in class org.hibernate.test.Child where
c.parent.count=66 order by c.parent.count" );
+ parse( "select c, c.parent, c.parent.count from c in class
org.hibernate.test.Child order by c.parent.count" );
+ parse( "FROM p IN CLASS org.hibernate.test.Parent WHERE p.count = ?" );
+ parse( "select count(*) from org.hibernate.test.Container as c join c.components
as ce join ce.simple as s where ce.name='foo'" );
+ parse( "select c, s from org.hibernate.test.Container as c join c.components as ce
join ce.simple as s where ce.name='foo'" );
+ parse( "from s in class org.hibernate.test.Simple" );
+ parse( "from m in class org.hibernate.test.Many" );
+ parse( "from o in class org.hibernate.test.One" );
+ parse( "from c in class org.hibernate.test.Container" );
+ parse( "from o in class org.hibernate.test.Child" );
+ parse( "from o in class org.hibernate.test.MoreStuff" );
+ parse( "from o in class org.hibernate.test.Many" );
+ parse( "from o in class org.hibernate.test.Fee" );
+ parse( "from o in class org.hibernate.test.Qux" );
+ parse( "from o in class org.hibernate.test.Fumm" );
+ parse( "from o in class org.hibernate.test.Parent" );
+ parse( "from o in class org.hibernate.test.Simple" );
+ parse( "from o in class org.hibernate.test.Holder" );
+ parse( "from o in class org.hibernate.test.Part" );
+ parse( "from o in class org.hibernate.test.Baz" );
+ parse( "from o in class org.hibernate.test.Vetoer" );
+ parse( "from o in class org.hibernate.test.Sortable" );
+ parse( "from o in class org.hibernate.test.Contained" );
+ parse( "from o in class org.hibernate.test.Circular" );
+ parse( "from o in class org.hibernate.test.Stuff" );
+ parse( "from o in class org.hibernate.test.Immutable" );
+ parse( "from o in class org.hibernate.test.Container" );
+ parse( "from o in class org.hibernate.test.One" );
+ parse( "from o in class org.hibernate.test.Foo" );
+ parse( "from o in class org.hibernate.test.Fo" );
+ parse( "from o in class org.hibernate.test.Glarch" );
+ parse( "from o in class org.hibernate.test.Fum" );
+ parse( "from c in class org.hibernate.test.C2 where 1=1 or 1=1" );
+ parse( "from b in class org.hibernate.test.B" );
+ parse( "from a in class org.hibernate.test.A" );
+ parse( "from b in class org.hibernate.test.B" );
+ parse( "from org.hibernate.test.E e join e.reverse as b where b.count=1" );
+ parse( "from org.hibernate.test.E e join e.as as b where b.count=1" );
+ parse( "from org.hibernate.test.B" );
+ parse( "from org.hibernate.test.C1" );
+ parse( "from org.hibernate.test.C2" );
+ parse( "from org.hibernate.test.E e, org.hibernate.test.A a where e.reverse =
a.forward and a = ?" );
+ parse( "from org.hibernate.test.E e join fetch e.reverse" );
+ parse( "from org.hibernate.test.E e" );
+ parse( "select max(s.count) from s in class org.hibernate.test.Simple" );
+ parse( "select new org.hibernate.test.S(s.count, s.address) from s in class
org.hibernate.test.Simple" );
+ parse( "select max(s.count) from s in class org.hibernate.test.Simple" );
+ parse( "select count(*) from s in class org.hibernate.test.Simple" );
+ parse( "from s in class org.hibernate.test.Simple where s.name=:name and
s.count=:count" );
+ parse( "from s in class org.hibernate.test.Simple where s.name in (:several0_,
:several1_)" );
+ parse( "from s in class org.hibernate.test.Simple where s.name in (:stuff0_,
:stuff1_)" );
+ parse( "from org.hibernate.test.Simple s where s.name=?" );
+ parse( "from org.hibernate.test.Simple s where s.name=:name" );
+ parse( "from s in class org.hibernate.test.Simple where upper( s.name )
='SIMPLE 1'" );
+ parse( "from s in class org.hibernate.test.Simple where not( upper( s.name )
='yada' or 1=2 or 'foo'='bar' or not('foo'='foo')
or 'foo' like 'bar' )" );
+ parse( "from s in class org.hibernate.test.Simple where lower( s.name || '
foo' ) ='simple 1 foo'" );
+ parse( "from s in class org.hibernate.test.Simple where upper( s.other.name )
='SIMPLE 2'" );
+ parse( "from s in class org.hibernate.test.Simple where not ( upper( s.other.name
) ='SIMPLE 2' )" );
+ parse( "select distinct s from s in class org.hibernate.test.Simple where ( (
s.other.count + 3 ) = (15*2)/2 and s.count = 69) or ( ( s.other.count + 2 ) / 7 ) =
2" );
+ parse( "select s from s in class org.hibernate.test.Simple where ( ( s.other.count
+ 3 ) = (15*2)/2 and s.count = 69) or ( ( s.other.count + 2 ) / 7 ) = 2 order by
s.other.count" );
+ parse( "select sum(s.count) from s in class org.hibernate.test.Simple group by
s.count having sum(s.count) > 10" );
+ parse( "select s.count from s in class org.hibernate.test.Simple group by s.count
having s.count = 12" );
+ parse( "select s.id, s.count, count(t), max(t.date) from s in class
org.hibernate.test.Simple, t in class org.hibernate.test.Simple where s.count = t.count
group by s.id, s.count order by s.count" );
+ parse( "from s in class org.hibernate.test.Simple" );
+ parse( "from s in class org.hibernate.test.Simple where s.name = ?" );
+ parse( "from s in class org.hibernate.test.Simple where s.name = ? and
upper(s.name) = ?" );
+ parse( "from s in class org.hibernate.test.Simple where s.name = :foo and
upper(s.name) = :bar or s.count=:count or s.count=:count + 1" );
+ parse( "select s.id from s in class org.hibernate.test.Simple" );
+ parse( "select all s, s.other from s in class org.hibernate.test.Simple where s =
:s" );
+ parse( "from s in class org.hibernate.test.Simple where s.name in (:name_list0_,
:name_list1_) and s.count > :count" );
+ parse( "from org.hibernate.test.Simple s" );
+ parse( "from org.hibernate.test.Simple s" );
+ parse( "from org.hibernate.test.Assignable" );
+ parse( "from org.hibernate.test.Category" );
+ parse( "from org.hibernate.test.Simple" );
+ parse( "from org.hibernate.test.A" );
+ parse( "from foo in class org.hibernate.test.Foo where foo.string=?" );
+ parse( "from foo in class org.hibernate.test.Foo" );
+ parse( "from org.hibernate.test.Po po, org.hibernate.test.Lower low where low.mypo
= po" );
+ parse( "from org.hibernate.test.Po po join po.set as sm where sm.amount >
0" );
+ parse( "from org.hibernate.test.Po po join po.top as low where low.foo =
'po'" );
+ parse( "from org.hibernate.test.SubMulti sm join sm.children smc where smc.name
> 'a'" );
+ parse( "select s, ya from org.hibernate.test.Lower s join s.yetanother ya"
);
+ parse( "from org.hibernate.test.Lower s1 join s1.bag s2" );
+ parse( "from org.hibernate.test.Lower s1 left join s1.bag s2" );
+ parse( "select s, a from org.hibernate.test.Lower s join s.another a" );
+ parse( "select s, a from org.hibernate.test.Lower s left join s.another a"
);
+ parse( "from org.hibernate.test.Top s, org.hibernate.test.Lower ls" );
+ parse( "from org.hibernate.test.Lower ls join ls.set s where s.name >
'a'" );
+ parse( "from org.hibernate.test.Po po join po.list sm where sm.name >
'a'" );
+ parse( "from org.hibernate.test.Lower ls inner join ls.another s where s.name is
not null" );
+ parse( "from org.hibernate.test.Lower ls where ls.other.another.name is not
null" );
+ parse( "from org.hibernate.test.Multi m where m.derived like 'F%'"
);
+ parse( "from org.hibernate.test.SubMulti m where m.derived like 'F%'"
);
+ parse( "select s from org.hibernate.test.SubMulti as sm join sm.children as s
where s.amount>-1 and s.name is null" );
+ parse( "select elements(sm.children) from org.hibernate.test.SubMulti as sm"
);
+ parse( "select distinct sm from org.hibernate.test.SubMulti as sm join sm.children
as s where s.amount>-1 and s.name is null" );
+ parse( "select distinct s from s in class org.hibernate.test.SubMulti where
s.moreChildren[1].amount < 1.0" );
+ parse( "from s in class org.hibernate.test.TrivialClass where s.id = 2" );
+ parse( "select s.count from s in class org.hibernate.test.Top" );
+ parse( "from s in class org.hibernate.test.Lower where
s.another.name='name'" );
+ parse( "from s in class org.hibernate.test.Lower where
s.yetanother.name='name'" );
+ parse( "from s in class org.hibernate.test.Lower where
s.yetanother.name='name' and s.yetanother.foo is null" );
+ parse( "from s in class org.hibernate.test.Top where s.count=1" );
+ parse( "select s.count from s in class org.hibernate.test.Top, ls in class
org.hibernate.test.Lower where ls.another=s" );
+ parse( "select elements(ls.bag), elements(ls.set) from ls in class
org.hibernate.test.Lower" );
+ parse( "from s in class org.hibernate.test.Lower" );
+ parse( "from s in class org.hibernate.test.Top" );
+ parse( "from sm in class org.hibernate.test.SubMulti" );
+ parse( "select\n" +
+ "\n" +
+ "s from s in class org.hibernate.test.Top where s.count>0" );
+ parse( "from m in class org.hibernate.test.Multi where m.count>0 and
m.extraProp is not null" );
+ parse( "from m in class org.hibernate.test.Top where m.count>0 and m.name is
not null" );
+ parse( "from m in class org.hibernate.test.Lower where m.other is not null"
);
+ parse( "from m in class org.hibernate.test.Multi where m.other.id = 1" );
+ parse( "from m in class org.hibernate.test.SubMulti where m.amount > 0.0"
);
+ parse( "from m in class org.hibernate.test.Multi" );
+ parse( "from m in class org.hibernate.test.Multi where m.class = SubMulti"
);
+ parse( "from m in class org.hibernate.test.Top where m.class = Multi" );
+ parse( "from s in class org.hibernate.test.Top" );
+ parse( "from ls in class org.hibernate.test.Lower" );
+ parse( "from ls in class org.hibernate.test.Lower, s in elements(ls.bag) where
s.id is not null" );
+ parse( "from ls in class org.hibernate.test.Lower, s in elements(ls.set) where
s.id is not null" );
+ parse( "from o in class org.hibernate.test.Top" );
+ parse( "from o in class org.hibernate.test.Po" );
+ parse( "from ChildMap cm where cm.parent is not null" );
+ parse( "from ParentMap cm where cm.child is not null" );
+ parse( "from org.hibernate.test.Componentizable" );
+ }
+
+ public void testUnnamedParameter() throws Exception {
+ parse( "select foo, bar from org.hibernate.test.Foo foo left outer join foo.foo
bar where foo = ?" ); // Added '?' as a valid expression.
+ }
+
+ public void testInElements() throws Exception {
+ parse( "from bar in class org.hibernate.test.Bar, foo in
elements(bar.baz.fooArray)" ); // Added collectionExpr as a valid 'in'
clause.
+// parse( "from org.hibernate.test.Bar bar, foo in elements(bar.baz.fooArray)"
); // Added collectionExpr as a valid 'in' clause.
+ }
+
+ public void testDotElements() throws Exception {
+ parse( "select distinct foo from baz in class org.hibernate.test.Baz, foo in
elements(baz.fooArray)" );
+ parse( "select foo from baz in class org.hibernate.test.Baz, foo in
elements(baz.fooSet)" );
+ parse( "select foo from baz in class org.hibernate.test.Baz, foo in
elements(baz.fooArray)" );
+ parse( "from org.hibernate.test.Baz baz where 'b' in
elements(baz.collectionComponent.nested.foos) and 1.0 in
elements(baz.collectionComponent.nested.floats)" );
+ }
+
+ public void testSelectAll() throws Exception {
+ parse( "select all s, s.other from s in class org.hibernate.test.Simple where s =
:s" );
+ }
+
+ public void testNot() throws Exception {
+ // Cover NOT optimization in HqlParser
+ parse( "from eg.Cat cat where not ( cat.kittens.size < 1 )" );
+ parse( "from eg.Cat cat where not ( cat.kittens.size > 1 )" );
+ parse( "from eg.Cat cat where not ( cat.kittens.size >= 1 )" );
+ parse( "from eg.Cat cat where not ( cat.kittens.size <= 1 )" );
+ parse( "from eg.DomesticCat cat where not ( cat.name between 'A' and
'B' ) " );
+ parse( "from eg.DomesticCat cat where not ( cat.name not between 'A' and
'B' ) " );
+ parse( "from eg.Cat cat where not ( not cat.kittens.size <= 1 )" );
+ parse( "from eg.Cat cat where not not ( not cat.kittens.size <= 1 )" );
+ }
+
+ public void testOtherSyntax() throws Exception {
+ parse( "select bar from org.hibernate.test.Bar bar order by ((bar.x -
:valueX)*(bar.x - :valueX))" );
+ parse( "from bar in class org.hibernate.test.Bar, foo in
elements(bar.baz.fooSet)" );
+ parse( "from one in class org.hibernate.test.One, many in elements(one.manies)
where one.id = 1 and many.id = 1" );
+ parse( "from org.hibernate.test.Inner _inner join _inner.middles middle" );
+ parse( "FROM m IN CLASS org.hibernate.test.Master WHERE NOT EXISTS ( FROM d IN
elements(m.details) WHERE NOT d.i=5 )" );
+ parse( "FROM m IN CLASS org.hibernate.test.Master WHERE NOT 5 IN ( SELECT d.i FROM
d IN elements(m.details) )" );
+ parse( "SELECT m FROM m IN CLASS org.hibernate.test.Master, d IN
elements(m.details) WHERE d.i=5" );
+ parse( "SELECT m FROM m IN CLASS org.hibernate.test.Master, d IN
elements(m.details) WHERE d.i=5" );
+ parse( "SELECT m.id FROM m IN CLASS org.hibernate.test.Master, d IN
elements(m.details) WHERE d.i=5" );
+ // I'm not sure about these... [jsd]
+// parse("select bar.string, foo.string from bar in class
org.hibernate.test.Bar inner join bar.baz as baz inner join elements(baz.fooSet) as foo
where baz.name = 'name'");
+// parse("select bar.string, foo.string from bar in class
org.hibernate.test.Bar, bar.baz as baz, elements(baz.fooSet) as foo where baz.name =
'name'");
+// parse("select count(*) where this.amount>-1 and this.name is
null");
+// parse("from sm in class org.hibernate.test.SubMulti where exists
sm.children.elements");
+ }
+
+ public void testEjbqlExtensions() throws Exception {
+ parse( "select object(a) from Animal a where a.mother member of a.offspring"
);
+ parse( "select object(a) from Animal a where a.offspring is empty" );
+ }
+
+ public void testEmptyFilter() throws Exception {
+ parseFilter( "" ); // Blank is a legitimate filter.
+ }
+
+ public void testOrderByFilter() throws Exception {
+ parseFilter( "order by this.id" );
+ }
+
+ public void testRestrictionFilter() throws Exception {
+ parseFilter( "where this.name = ?" );
+ }
+
+ public void testNoFrom() throws Exception {
+ System.out.println( "***** This test ensures that an error is detected ERROR
MESSAGES ARE OKAY! *****" );
+ HqlParser parser = buildHqlParser( "" );
+ parser.statement();
+ assertEquals( "Parser allowed no FROM clause!", 1,
parser.getParseErrorHandler().getErrorCount() );
+ System.out.println( "***** END OF ERROR TEST *****" );
+ }
+
+ public void testHB1042() throws Exception {
+ parse( "select x from fmc_web.pool.Pool x left join x.containers c0 where
(upper(x.name) = upper(':') and c0.id = 1)" );
+ }
+
+ public void testKeywordInPath() throws Exception {
+ // The keyword 'order' used as a property name.
+ parse( "from Customer c where c.order.status = 'argh'" );
+ // The keyword 'order' and 'count' used as a property name.
+ parse( "from Customer c where c.order.count > 3" );
+ // The keywords 'where', 'order' and 'count' used as a property
name.
+ parse( "select c.where from Customer c where c.order.count > 3" );
+ parse( "from Interval i where i.end <:end" );
+ parse( "from Letter l where l.case = :case" );
+ }
+
+ public void testPathologicalKeywordAsIdentifier() throws Exception {
+ // Super evil badness... a legitimate keyword!
+ parse( "from Order order" );
+ //parse( "from Order order join order.group" );
+ parse( "from X x order by x.group.by.from" );
+ parse( "from Order x order by x.order.group.by.from" );
+ parse( "select order.id from Order order" );
+ parse( "select order from Order order" );
+ parse( "from Order order where order.group.by.from is not null" );
+ parse( "from Order order order by order.group.by.from" );
+ // Okay, now this is getting silly.
+ parse( "from Group as group group by group.by.from" );
+ }
+
+ public void testHHH354() throws Exception {
+ parse( "from Foo f where f.full = 'yep'");
+ }
+
+ public void testWhereAsIdentifier() throws Exception {
+ // 'where' as a package name
+ parse( "from where.Order" );
+ }
+
+ public void testEjbqlKeywordsAsIdentifier() throws Exception {
+ parse( "from org.hibernate.test.Bar bar where bar.object.id = ? and
bar.object.class = ?" );
+ }
+
+ public void testConstructorIn() throws Exception {
+ parse( "from org.hibernate.test.Bar bar where (b.x, b.y, b.z) in (select foo, bar,
baz from org.hibernate.test.Foo)" );
+ }
+
+ public void testMultiByteCharacters() throws Exception {
+ parse ("from User user where user.name like '%nn\u4e2dnn%'");
+ // Test for HHH-558
+ parse ("from User user where user.\u432d like '%\u4e2d%'");
+ parse ("from \u432d \u432d where \u432d.name like '%fred%'");
+ }
+
+ public void testHHH719() throws Exception {
+ // Some SQLs have function names with package qualifiers.
+ parse("from Foo f order by com.fooco.SpecialFunction(f.id)");
+ }
+
+ public void testHHH1107() throws Exception {
+ parse("from Animal where zoo.address.street = '123 Bogus St.'");
+ }
+
+
+ public void testHHH1247() throws Exception {
+ parse("select distinct user.party from
com.itf.iceclaims.domain.party.user.UserImpl user inner join user.party.$RelatedWorkgroups
relatedWorkgroups where relatedWorkgroups.workgroup.id = :workgroup and
relatedWorkgroups.effectiveTime.start <= :datesnow and
relatedWorkgroups.effectiveTime.end > :dateenow ");
+ }
+ public void testLineAndColumnNumber() throws Exception {
+ AST ast = doParse("from Foo f\nwhere f.name = 'fred'",false);
+ // Find some of the nodes and check line and column values.
+ ASTIterator iter = new ASTIterator(ast);
+ boolean foundFoo = false;
+ boolean foundName = false;
+ while (iter.hasNext())
+ {
+ AST n = iter.nextNode();
+ if ("Foo".equals(n.getText()))
+ {
+ if (foundFoo)
+ fail("Already found 'Foo'!");
+ foundFoo = true;
+ Node node = ( Node )n;
+ assertEquals(1,node.getLine());
+ assertEquals(6,node.getColumn());
+ }
+ else if ("name".equals(n.getText()))
+ {
+ if (foundName)
+ fail("Already found 'name'!");
+ foundName = true;
+ Node node = ( Node )n;
+ assertEquals(2,node.getLine());
+ assertEquals(9,node.getColumn());
+ }
+ }
+ assertTrue(foundFoo);
+ assertTrue(foundName);
+ }
+
+
+ private void parse(String input) throws RecognitionException, TokenStreamException {
+ doParse( input, false );
+ }
+
+ private void parseFilter(String input) throws TokenStreamException, RecognitionException
{
+ doParse( input, true );
+ }
+
+ public static AST doParse(String input, boolean isFilter) throws RecognitionException,
TokenStreamException {
+ System.out.println( "input: ->" + ASTPrinter.escapeMultibyteChars(input) +
"<-" );
+ HqlParser parser = buildHqlParser( input );
+ if ( isFilter ) {
+ parser.filterStatement();
+ }
+ else {
+ parser.statement();
+ }
+ AST ast = parser.getAST();
+ show( ast, "AST [" + ast.toStringTree() + "]" );
+ assertEquals( "At least one error occurred during parsing!", 0,
parser.getParseErrorHandler().getErrorCount() );
+ return ast;
+ }
+
+ private static HqlParser buildHqlParser(String hql) {
+ return new HqlParser(
+ hql,
+ new HqlParser.Context() {
+ public boolean isEntityName(String name) {
+ return false;
+ }
+
+ public String getImportedName(String name) {
+ return null;
+ }
+
+ public boolean isRegisteredFunctionName(String name) {
+ return false;
+ }
+ }
+ );
+ }
+
+}
Modified: core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties 2009-01-06 17:14:14
UTC (rev 15746)
+++ core/branches/SQL_GEN_REDESIGN/src/test/resources/log4j.properties 2009-01-06 20:11:13
UTC (rev 15747)
@@ -30,4 +30,5 @@
log4j.logger.org.hibernate.test=info
log4j.logger.org.hibernate.tool.hbm2ddl=debug
-log4j.logger.org.hibernate.sql.ordering.antlr.OrderByFragmentTranslator=trace
\ No newline at end of file
+log4j.logger.org.hibernate.sql.ast.ordering.OrderByFragmentTranslator=trace
+log4j.logger.org.hibernate.hql.ast=trace
\ No newline at end of file