[hibernate-commits] Hibernate SVN: r15917 - in core/branches/SQL_GEN_REDESIGN/src/main/antlr: sql and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Mon Feb 9 13:30:53 EST 2009


Author: steve.ebersole at jboss.com
Date: 2009-02-09 13:30:53 -0500 (Mon, 09 Feb 2009)
New Revision: 15917

Added:
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/resolve.g
Modified:
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g
   core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g
Log:
HHH-2407 : HQL translation rework ->
HHH-3687 : parse (phase1)
HHH-3688 : normalize (phase2)

Modified: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g	2009-02-09 11:19:30 UTC (rev 15916)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/normalize.g	2009-02-09 18:30:53 UTC (rev 15917)
@@ -63,6 +63,10 @@
 
 tokens {
 	PROPERTY_REF;
+	INDEXED_COLLECTION_ACCESS_PERSISTER_REF;
+	INDEXED_COLLECTION_ELEMENT_REF;
+	ASSOCIATION_NAME;
+	INDEX_VALUE_CORRELATION;
 }
 
 
@@ -70,16 +74,27 @@
 {
     private static Logger log = LoggerFactory.getLogger( GeneratedHqlNormalizer.class );
 
+    private AST currentFromClause;
+
 	private int ordinalParamCount = 0;
+	private int statementDepth = 0;
 
+	protected final int getStatementDepth() {
+	    return statementDepth;
+    }
 
+    protected final boolean isSubquery() {
+        return statementDepth > 1;
+    }
+
+
     // persister reference related actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     protected AST normalizeEntityName(AST node) throws SemanticException {
         throw new UnsupportedOperationException( "must be overridden!" );
     }
 
-    protected AST normalizeAlias(AST node) {
+    protected final AST normalizeAlias(AST node) {
         if ( node != null ) {
             return node;
         }
@@ -133,6 +148,10 @@
         throw new UnsupportedOperationException( "must be overridden!" );
     }
 
+	protected AST normalizeUnqualifiedPropertyReferenceSource(AST propertyName) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
     protected AST normalizeIndexedRoot(AST alias) {
         throw new UnsupportedOperationException( "must be overridden!" );
     }
@@ -145,103 +164,109 @@
         throw new UnsupportedOperationException( "must be overridden!" );
     }
 
+    protected AST normalizeIntermediateIndexOperation(AST collectionPath, AST selector) throws SemanticException {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
 
-	// Statement node BEGIN/END handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    protected AST normalizeTerminalIndexOperation(AST collectionPath, AST selector) throws SemanticException {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
 
+    protected void applyWithFragment(AST withFragment) {
+	}
+
+
+	// Statement node BEGIN/END handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 	protected void pushStatement(AST statementNode) {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
 	protected void popStatement() {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
 
-	// property-path context pushing/popping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// property-path context pushing/popping ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 	protected void pushFromClausePropertyPathContext(AST joinType, AST fetch, AST alias, AST propertyFetch) {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
 	protected void popFromClausePropertyPathContext() {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
     protected void pushSelectClausePropertyPathContext() {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
     protected void popSelectClausePropertyPathContext() {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
 	protected void pushOnFragmentPropertyPathContext(AST rhsPersisterReference) {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
-	protected void popOnFragmentPropertyPathContext() {
+	protected AST popOnFragmentPropertyPathContext() {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
 	protected void pushWithFragmentPropertyPathContext(AST rhsPersisterReference) {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
 	protected void popWithFragmentPropertyPathContext() {
+        throw new UnsupportedOperationException( "must be overridden!" );
 	}
 
 
-
-
     // function processing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
     protected void startingFunction() {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
     protected void endingFunction() {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
 
-
-
     protected void registerSelectItem(AST selectItem) {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
+    private void startQuerySpec(AST querySpecIn) {
+        statementDepth++;
+        applyCollectionFilter(querySpecIn);
+    }
 
+    private void endQuerySpec(AST querySpec) {
+        postProcessQuery( querySpec );
+        --statementDepth;
+    }
 
-
-
-	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) {
+    protected void applyCollectionFilter(AST querySpecIn) {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
-
-	// 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 postProcessQuery(AST query) {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
 
-    protected void registerSelectExpression(AST selectExpression) {
+    protected AST buildRootEntityPersisterReference(AST persisterReferenceNode, AST entityName, AST alias, AST filter, AST propertyFetch) {
+        AST rtn = #( persisterReferenceNode, entityName, alias, filter );
+		registerPersisterReference( rtn );
+		if ( propertyFetch != null ) {
+		    registerPropertyFetchNode( rtn );
+        }
+        return rtn;
     }
 
-    protected AST handleSelectedPropertyRef(AST propertyRef) {
-        return propertyRef;
+    protected void registerPropertyFetchNode(AST persisterReference) {
+        throw new UnsupportedOperationException( "must be overridden!" );
     }
-
 }
 
 // Statement rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -311,9 +336,9 @@
  */
 insertStatement :
     #(
-        INSERT { pushStatement( #insertStatement ); }
-            intoClause
-            queryExpression { popStatement(); }
+        i:INSERT { pushStatement( #insertStatement ); }
+            ic:intoClause
+            qe:queryExpression { popStatement(); }
     )
 ;
 
@@ -373,51 +398,52 @@
     queryExpression
 ;
 
-querySpec :
-    #( QUERY_SPEC selectFrom ( whereClause )? ( groupByClause ( havingClause )? )? )
+querySpec { startQuerySpec(#querySpec_in); } :
+    #( QUERY_SPEC selectFrom ( whereClause )? ( groupByClause ( havingClause )? )? ) { endQuerySpec(#querySpec); }
 ;
 
 
 selectFrom :
-    #( SELECT_FROM fromClause (selectClause)? )
+    #( SELECT_FROM fromClause (sc:selectClause)? )
 ;
 
 
 // table/persister related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-fromClause :
-    #( FROM (persisterSpace)+ )
+fromClause! :
+    #( f:FROM {currentFromClause=#f;} (persisterSpace)+ {currentFromClause=null;} ) {
+        #fromClause = #f;
+    }
 ;
 
-persisterSpace :
-    #( PERSISTER_SPACE entityPersisterReference ( explicitJoin )* )
+persisterSpace! :
+    #( PERSISTER_SPACE pr:entityPersisterReference {currentFromClause.addChild( #pr );} ( explicitPersisterJoin | explicitPropertyJoin )* )
 ;
 
 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 );
+    #( epr:ENTITY_PERSISTER_REF en:ENTITY_NAME a:ALIAS (f:FILTER)? (pf:PROP_FETCH)? ) {
+        #entityPersisterReference = buildRootEntityPersisterReference(
+                #epr,
+                normalizeEntityName( #en ),
+                normalizeAlias( #a ),
+                #f,
+                #pf
+        );
 	}
 ;
 
-explicitJoin :
-    explicitPersisterJoin
-    | explicitPropertyJoin
-;
-
-explicitPersisterJoin :
+explicitPersisterJoin!:
     #(
         j:PERSISTER_JOIN (
-            CROSS entityPersisterReference
-            | qualifiedJoinType e:entityPersisterReference (on:onFragment[#e])?
+            CROSS cjpr:entityPersisterReference {
+                currentFromClause.addChild( #cjpr );
+            }
+            | jt:qualifiedJoinType rhs:entityPersisterReference {pushOnFragmentPropertyPathContext(#rhs);} on:onFragment {
+                AST lhs = popOnFragmentPropertyPathContext();
+                lhs.addChild( #( #j, #jt, #rhs, #on ) );
+            }
         )
-    ) {
-        #j.setType( JOIN );
-        #j.setText( "join" );
-    }
+    )
 ;
 
 explicitPropertyJoin! :
@@ -429,10 +455,8 @@
 	| INNER
 ;
 
-onFragment[ AST rhsPersisterReference ] :
-    #( o:ON { pushOnFragmentPropertyPathContext( rhsPersisterReference ); } sc:searchCondition ) {
-		#onFragment = #( o, sc );
-	}
+onFragment :
+    #( o:ON sc:searchCondition )
 ;
 
 withFragment[ AST rhsPropertyReference ] :
@@ -927,7 +951,7 @@
 propertyReference :
     (unqualifiedPropertyReferenceCheck) => unqualifiedPropertyReference
     | pathedPropertyReference
-    | indexOperation
+    | terminalIndexOperation
 ;
 
 /**
@@ -973,7 +997,7 @@
     (persisterReferenceAliasCheck) => a:IDENT { #pathedPropertyReferenceSource = normalizeQualifiedRoot( #a ); }
     | (unqualifiedPropertyReferenceCheck) => pr:IDENT { #pathedPropertyReferenceSource = normalizeUnqualifiedRoot( #pr ); }
     | intermediatePathedPropertyReference
-    | i:indexOperation { #pathedPropertyReferenceSource = normalizeIndexedRoot( #i ); }
+    | intermediateIndexOperation
 ;
 
 /**
@@ -986,31 +1010,31 @@
     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 );
+intermediateIndexOperation! :
+    #( INDEX_OP collection:indexOperationSource selector:indexSelector ) {
+        #intermediateIndexOperation = normalizeIntermediateIndexOperation( #collection, #selector );
     }
-    ;
+;
 
+terminalIndexOperation! :
+    #( INDEX_OP collection:indexOperationSource selector:indexSelector ) {
+        #terminalIndexOperation = normalizeTerminalIndexOperation( #collection, #selector );
+    }
+;
+
+indexOperationSource :
+    #( DOT pathedPropertyReferenceSource IDENT )
+    | (unqualifiedPropertyReferenceCheck) => pr:IDENT {
+        #indexOperationSource = #( [DOT], normalizeUnqualifiedPropertyReferenceSource( #pr ), #pr );
+    }
+;
+
 indexSelector
 	: valueExpression
 //	| literal

Modified: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g	2009-02-09 11:19:30 UTC (rev 15916)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/parse.g	2009-02-09 18:30:53 UTC (rev 15917)
@@ -66,7 +66,7 @@
 	DYNAMIC_INSTANTIATION_ARG;
 	ENTITY_NAME;
 	ENTITY_PERSISTER_REF;
-	FILTER_ENTITY;
+	FILTER;
 	GENERIC_FUNCTION;
 	INDEX_OP;
 	INSERTABILITY_SPEC;
@@ -258,9 +258,10 @@
 
 // filter rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-filterStatement :
+filterStatement[String collectionRole] :
     filteredSelectFrom (whereClause)? ( groupByClause ( havingClause )? )? (orderByClause)? {
-	    #filterStatement = #( [QUERY,"query"], #filterStatement );
+        AST querySpec = #( [QUERY_SPEC, "filter-query-spec"], [FILTER, collectionRole], #filterStatement );
+	    #filterStatement = #( [QUERY,"query"], querySpec );
     }
 ;
 
@@ -272,7 +273,7 @@
 		// Create an artificial token so the 'FROM' can be placed
 		// before the SELECT in the tree to make tree processing
 		// simpler.
-		#filteredSelectFrom = #( [SELECT_FROM,"SELECT_FROM"], #f, #s );
+		#filteredSelectFrom = #( [SELECT_FROM,"select-from"], #f, #s );
 	}
 ;
 
@@ -372,7 +373,7 @@
  */
 sortSpecification :
     sortKey (collationSpecification)? (orderingSpecification)? {
-        #sortSpecification = #( [SORT_SPEC, "{sort specification}"], #sortSpecification );
+        #sortSpecification = #( [SORT_SPEC, "sort-specification"], #sortSpecification );
     }
 ;
 
@@ -427,7 +428,7 @@
 		// Create an artificial token so the 'FROM' can be placed
 		// before the SELECT in the tree to make tree processing
 		// simpler.
-		#selectFrom = #( [SELECT_FROM,"SELECT_FROM"], f, s );
+		#selectFrom = #( [SELECT_FROM,"select-from"], f, s );
 	}
 ;
 
@@ -501,10 +502,10 @@
     }
 ;
 
-crossJoin :
-    CROSS j:JOIN^ {prepareForCrossJoinElements();} mainEntityPersisterReference {
-        j.setType( PERSISTER_JOIN );
-        j.setText( "persister-join" );
+crossJoin! :
+    c:CROSS j:JOIN {prepareForCrossJoinElements();} rhs:mainEntityPersisterReference {
+        #crossJoin = #( [PERSISTER_JOIN,"persister-join"], #c, rhs );
+        transferTrackingInfo( #j, #crossJoin );
     }
 ;
 

Added: core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/resolve.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/resolve.g	                        (rev 0)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/hql/resolve.g	2009-02-09 18:30:53 UTC (rev 15917)
@@ -0,0 +1,854 @@
+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.resolve;
+
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.ast.DetailedSemanticException;
+}
+
+/**
+ * An Antlr tree parser for "resolving" an HQL AST.  Essentially here we are concerned with creating a generic
+ * SQL AST.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+class GeneratedHqlResolver extends TreeParser;
+
+options {
+	importVocab = HqlNormalize;
+	exportVocab = HqlResolve;
+	buildAST = true;
+}
+
+tokens {
+    COLUMN;
+    NAME;
+}
+
+
+{
+    private static Logger log = LoggerFactory.getLogger( GeneratedHqlResolver.class );
+
+    protected AST resolveEntityPersister(AST entityName, AST alias, AST filter) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST resolveCollectionPersister(AST collectionRole, AST alias) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void applyPropertyJoin(AST lhs, AST rhs, AST propertyName, AST joinType, AST with) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST generateIndexValueCondition(AST lhs, AST rhs, AST propertyName, AST selector ) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void appendSearchCondition(AST condition, AST container) {
+        if ( container.getFirstChild() == null ) {
+            container.setFirstChild( condition );
+        }
+        else {
+            AST and = #( [AND,"and"], container.getFirstChild() );
+            and.addChild( condition );
+            container.setFirstChild( and );
+        }
+    }
+
+    protected void applyVersionedUpdate(AST updateStatement) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+    
+    protected void postProcessQuery(AST whereClause) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void startSelectClause() {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void finishSelectClause() {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void startFunction() {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected void finishFunction() {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST resolvePropertyReference(AST persisterAlias, AST propertyName) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+
+    protected AST resolveAliasReference(AST aliasReference) {
+        throw new UnsupportedOperationException( "must be overridden!" );
+    }
+}
+
+
+// Statement rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * The main grammar rule
+ */
+statement :
+    updateStatement
+    | deleteStatement
+    | insertStatement
+    | selectStatement
+;
+
+
+// <tt>UPDATE</tt> statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an <tt>UPDATE</tt> statement
+ */
+updateStatement :
+    #( u:UPDATE (v:VERSIONED)? en:ENTITY_NAME a:ALIAS setClause (whereClause)? ) {
+        if ( #v != null ) {
+            applyVersionedUpdate( #updateStatement );
+        }
+    }
+;
+
+setClause :
+    #( SET (assignment)+ )
+;
+
+assignment :
+    #( ASSIGNMENT_OP assignmentField newValue )
+;
+
+assignmentField :
+    propertyReference
+;
+
+newValue :
+    valueExpression
+;
+
+
+
+// <tt>DELETE</tt> statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>DELETE</tt> statement
+ */
+deleteStatement :
+    #( d:DELETE en:ENTITY_NAME a:ALIAS (whereClause)? )
+;
+
+
+// <tt>INSERT</tt> statement ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * Recognize an HQL <tt>INSERT</tt> statement
+ */
+insertStatement :
+    #( i:INSERT ic:intoClause qe:queryExpression )
+;
+
+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 queryExpression (orderByClause)? )
+;
+
+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! :
+    #( qs:QUERY_SPEC #(SELECT_FROM f:fromClause s:selectClause) (w:whereClause)? ( g:groupByClause ( h:havingClause )? )? ) {
+        #querySpec = #( #qs, #s, #f, #w, #g, #h );
+        postProcessQuery( #querySpec );
+    }
+;
+
+
+selectFrom :
+    #( SELECT_FROM fromClause selectClause )
+;
+
+
+// table/persister related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+fromClause :
+    #( FROM (entityPersisterReference)+ )
+;
+
+persisterReference :
+    entityPersisterReference
+    | collectionPersisterReference
+    | indexedCollectionElementPersisterReference
+;
+
+entityPersisterReference! {
+    AST lhs = null;
+} :
+    #( epr:ENTITY_PERSISTER_REF en:ENTITY_NAME a:ALIAS (f:FILTER)? { lhs = resolveEntityPersister( #en, #a, #f ); } joins[lhs] ) {
+        #entityPersisterReference = lhs;
+    }
+;
+
+collectionPersisterReference! {
+    AST lhs = null;
+} :
+    #( COLLECTION_PERSISTER_REF cr:COLLECTION_ROLE a:ALIAS { lhs = resolveCollectionPersister( #cr, #a ); } joins[lhs] ) {
+        #collectionPersisterReference = lhs;
+    }
+;
+
+indexedCollectionElementPersisterReference! {
+    AST lhs = null;
+} :
+    #( INDEXED_COLLECTION_ACCESS_PERSISTER_REF cr:COLLECTION_ROLE a:ALIAS { lhs = resolveCollectionPersister( #cr, #a ); } indexSelector[lhs] joins[lhs] )
+;
+
+indexSelector[AST lhs] :
+    #( INDEX_VALUE_CORRELATION iv:selectedIndexValue )
+;
+
+selectedIndexValue! :
+    valueExpression
+;
+
+joins[AST lhs] :
+    ( persisterJoin[lhs] | propertyJoin[lhs] )*
+;
+
+persisterJoin![AST lhs] :
+    // NOTE : persister cross joins were mutated into root table references during normalize.
+    #( PERSISTER_JOIN jt:correlatedJoinType rhs:entityPersisterReference on:onFragment[lhs,rhs] ) {
+        lhs.addChild( #( [JOIN,"join"], #jt, #rhs, #on ) );
+    }
+;
+
+correlatedJoinType :
+    INNER
+    | LEFT
+    | RIGHT
+;
+
+onFragment[AST rhs, AST lhs] :
+    #( ON searchCondition )
+;
+
+propertyJoin![AST lhs] :
+    #( PROPERTY_JOIN jt:propertyJoinType pn:ASSOCIATION_NAME rhs:persisterReference (w:withFragment[lhs,#rhs])? ) {
+        applyPropertyJoin( lhs, #rhs, #pn, #jt, #w );
+    }
+;
+
+propertyJoinType:
+    INNER
+    | LEFT
+;
+
+
+withFragment[AST lhs, AST rhs] :
+    #( w:WITH searchCondition )
+;
+
+
+// select clause related rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+// todo : we need to tighten down exactly what is allowed in the select clause here...
+// todo : additionally certain nodes need to be interpretted differently when in select-clause versus other clauses:
+//      think of an ALIAS_REF; in select-clause this should be expanded to the full columns list; elsewhere to just the pk/fk
+
+// actually may need something more like a strategy based on context...
+
+selectClause :
+    #( SELECT {startSelectClause();} (d:DISTINCT)? rootSelectExpression {finishSelectClause();} )
+;
+
+rootSelectExpression :
+    #( SELECT_LIST explicitSelectList )
+    | #( SELECT_ITEM rootDynamicInstantiation )
+;
+
+explicitSelectList :
+    ( explicitSelectItem )+
+;
+
+explicitSelectItem :
+    #( SELECT_ITEM selectExpression )
+;
+
+selectExpression :
+    valueExpression ( ALIAS )?
+;
+
+rootDynamicInstantiation :
+    #( DYNAMIC_INSTANTIATION dynamicInstantiationArguments )
+;
+
+nestedDynamicInstantiation :
+    #( DYNAMIC_INSTANTIATION dynamicInstantiationArguments (ALIAS)? )
+;
+
+dynamicInstantiationArguments :
+    ( dynamicInstantiationArgument )+
+;
+
+dynamicInstantiationArgument :
+    #( DYNAMIC_INSTANTIATION_ARG ( nestedDynamicInstantiation | selectExpression ) )
+;
+
+
+
+// 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 :
+    persisterAliasReference
+    | caseExpression
+	| function
+	| collectionFunction
+	| collectionExpression
+	| literal
+	| parameter
+    | propertyReference
+;
+
+propertyReference! :
+    #( PROPERTY_REF a:ALIAS_REF pn:IDENT ) {
+        #propertyReference = resolvePropertyReference( #a, #pn );
+    }
+;
+
+nonCollectionPropertyReference :
+    pr:propertyReference
+;
+
+collectionPropertyReference :
+    pr:propertyReference
+;
+
+function {
+    startFunction();
+} :
+    ( standardFunction | setFunction ) {
+        finishFunction();
+    }
+;
+
+persisterAliasReference! :
+    a:ALIAS_REF {
+        #persisterAliasReference = resolveAliasReference( #a );
+    }
+;
+
+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 )
+;
+
+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 ( ASTERISK | ( ( DISTINCT | ALL )? ( propertyReference | literal ) ) ) )
+;
+
+collectionFunction :
+    #( MAXELEMENT collectionPropertyReference )
+    | #( MAXINDEX collectionPropertyReference )
+    | #( MINELEMENT collectionPropertyReference )
+    | #( MININDEX collectionPropertyReference )
+;
+
+collectionExpression :
+    #( ELEMENTS collectionPropertyReference )
+    #( INDICES collectionPropertyReference )
+;
+
+parameter :
+    PARAM
+    | 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
+;
+
+
+
+// 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/sql/common.g
===================================================================
--- core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g	2009-02-09 11:19:30 UTC (rev 15916)
+++ core/branches/SQL_GEN_REDESIGN/src/main/antlr/sql/common.g	2009-02-09 18:30:53 UTC (rev 15917)
@@ -36,6 +36,8 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
+import org.hibernate.util.StringHelper;
 }
 
 /**
@@ -197,6 +199,8 @@
     ORDER_BY;
     GROUP_BY;
 
+    ROW_VALUE_CONSTRUCTOR_LIST;
+
     // synthetic numeric literal types
     NUM_INT_LITERAL;
     NUM_LONG_LITERAL;
@@ -235,8 +239,39 @@
 {
 	private static final Logger log = LoggerFactory.getLogger( CommonHibernateParserSupport.class );
 
-    // Grammar actions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private int traceDepth = 0;
 
+	/**
+	 * {@inheritDoc}
+	 */
+	public void traceIn(String s) throws TokenStreamException {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = StringHelper.repeat( "-", (traceDepth++ * 2) ) + "->";
+		traceExecution( prefix + s );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void traceOut(String s) throws TokenStreamException {
+		if ( inputState.guessing > 0 ) {
+			return;
+		}
+		String prefix = "<-" + StringHelper.repeat( "-", (--traceDepth * 2) );
+		traceExecution( prefix + s );
+	}
+
+	/**
+	 * Perform trace logging.  Called from both {@link #traceIn} and {@link #traceOut}.
+	 *
+	 * @param msg The trace string
+	 */
+	protected void traceExecution(String msg) {
+		log.trace( msg );
+	}
+
 	public void showAST(AST ast) {
 	    showAST( ast, "AST" );
 	}




More information about the hibernate-commits mailing list