Author: steve.ebersole(a)jboss.com
Date: 2006-12-19 17:22:21 -0500 (Tue, 19 Dec 2006)
New Revision: 11004
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/JoinType.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/PhaseContextAwareNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java
Removed:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java
Modified:
branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
Log:
added initial basic select clause processing
Modified: branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g
===================================================================
--- branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-12-19 19:08:27 UTC (rev 11003)
+++ branches/HQL_ANTLR_2/Hibernate3/g2/resolve.g 2006-12-19 22:22:21 UTC (rev 11004)
@@ -44,10 +44,13 @@
PROPERTY_REF;
ENTITY_PERSISTER_REF;
COLLECTION_PERSISTER_REF;
+ PERSISTER_REF_REF;
BOGUS;
NAMED_PARAM;
ORDINAL_PARAM;
+
+ SELECT_CLAUSE;
}
@@ -125,7 +128,13 @@
protected void popWithFragmentPropertyPathContext() {
}
+ protected void pushSelectClausePropertyPathContext() {
+ }
+ protected void popSelectClausePropertyPathContext() {
+ }
+
+
// persister reference handling ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
protected AST buildEntityPersisterReference(AST entityName, AST alias, AST
propertyFetch) {
@@ -158,17 +167,32 @@
return param;
}
+ protected void injectSelectAlias( AST selectExpression, AST alias) {
+ }
+
+ protected void registerSelectExpression(AST selectExpression) {
+ }
+
+ protected AST handleSelectedPropertyRef(AST propertyRef) {
+ return propertyRef;
+ }
}
-// The main statement rule.
+///////////////////////////////////////////////////////////////////////////////
+// The main statement rule
+
statement
: selectStatement | updateStatement | deleteStatement | insertStatement
;
-// --- HQL statements ---
+///////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////
+// The statement sub-rules
+
selectStatement
- : query
+ : query ( ( m:MINUS | u:UNION ) (a:ALL)? query )*
;
updateStatement
@@ -183,6 +207,8 @@
: #(INSERT { pushStatement( #insertStatement ); } intoClause query { popStatement(); })
;
+///////////////////////////////////////////////////////////////////////////////
+
query
: #(QUERY { pushStatement( #query ); }
// The first phase places the FROM first to make processing the SELECT simpler.
@@ -195,14 +221,50 @@
)
;
-// TODO : for now, just copy over the entire subtree
selectClause
- : #(SELECT (subtree)* )
+ : #( SELECT { pushSelectClausePropertyPathContext(); } ( d:DISTINCT )? x:selectExprList
) {
+ #selectClause = #([SELECT_CLAUSE,"{select clause}"], #d, #x);
+ popSelectClausePropertyPathContext();
+ }
;
-// -- Language sub-elements --
+selectExprList
+ : ( selectExprValue )+
+ ;
+selectExprValue
+ : ( selectExpr | aliasedSelectExpr ) {
+ registerSelectExpression( #selectExprValue );
+ }
+ ;
+aliasedSelectExpr
+ : #( AS se:selectExpr i:identifier! ) {
+ injectSelectAlias( #se, #i );
+ #aliasedSelectExpr = #se;
+ }
+ ;
+
+// TODO : the old grammar had both literal and constant available as select expressions,
but that is probably not valid; it is certainly not valid for non-subqueries
+selectExpr
+ : (persisterReferenceAliasCheck) => persisterRefRef
+ | pr:propertyRef { #selectExpr = handleSelectedPropertyRef( #pr ); }
+ | arithmeticExpr
+ | count
+ | literal
+ | constant
+ ;
+
+persisterRefRef!
+ : alias:IDENT {
+ #persisterRefRef = #( [ PERSISTER_REF_REF, alias.getText() ] );
+ }
+ ;
+
+count
+ : #(COUNT ( DISTINCT | ALL )? ( propertyRef | literal | ROW_STAR ) )
+ ;
+
fromClause
: #( f:FROM rootFromElement ( explicitJoin | rootFromElement )* )
;
@@ -443,10 +505,6 @@
| #( INDICES propertyRef )
;
-count
- : #(COUNT ( DISTINCT | ALL )? ( aggregateExpr | ROW_STAR ) )
- ;
-
aggregateExpr
: expr
| collectionFunction
@@ -490,12 +548,16 @@
;
constant
- : literal
- | NULL
+ : NULL
| TRUE
| FALSE
+ | javaConstant
;
+javaConstant
+ : JAVA_CONSTANT
+ ;
+
literal
: NUM_INT
| NUM_LONG
Copied: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/JoinType.java
(from rev 11003,
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java)
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/JoinType.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -0,0 +1,62 @@
+package org.hibernate.hql.ast.common;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+/**
+ * Represents a canonical join type.
+ * <p/>
+ * Note that currently HQL really only supports inner and left outer joins
+ * (though cross joins can also be achieved). This is because joins in HQL
+ * are always defined in relation to a mapped association. However, when we
+ * start allowing users to specify ad-hoc joins this may need to change to
+ * allow the full spectrum of join types. Thus the others are provided here
+ * currently just for completeness and for future expansion.
+ *
+ * @author Steve Ebersole
+ */
+public class JoinType implements Serializable {
+ /**
+ * Represents an inner join.
+ */
+ public static final JoinType INNER = new JoinType( "inner" );
+ /**
+ * Represents a left outer join.
+ */
+ public static final JoinType LEFT = new JoinType( "left outer" );
+ /**
+ * Represents a right outer join.
+ */
+ public static final JoinType RIGHT = new JoinType( "right outer" );
+ /**
+ * Represents a cross join (aka a cartesian product).
+ */
+ public static final JoinType CROSS = new JoinType( "cross" );
+ /**
+ * Represents a full join.
+ */
+ public static final JoinType FULL = new JoinType( "full" );
+
+ private static final HashMap INSTANCES = new HashMap();
+ static {
+ INSTANCES.put( INNER.name, INNER );
+ INSTANCES.put( LEFT.name, LEFT );
+ INSTANCES.put( RIGHT.name, RIGHT );
+ INSTANCES.put( CROSS.name, CROSS );
+ INSTANCES.put( FULL.name, FULL );
+ }
+
+ private final String name;
+
+ private JoinType(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ private Object readResolve() {
+ return INSTANCES.get( name );
+ }
+}
Copied:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/PhaseContextAwareNode.java
(from rev 11003,
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java)
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/common/PhaseContextAwareNode.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -0,0 +1,18 @@
+package org.hibernate.hql.ast.common;
+
+import org.hibernate.hql.ast.PhaseContext;
+
+/**
+ * Injection service contract for nodes which require access to the current
+ * phase context during their lifetime.
+ *
+ * @author Steve Ebersole
+ */
+public interface PhaseContextAwareNode {
+ /**
+ * Inject a reference to the current {@link PhaseContext}.
+ *
+ * @param context The current {@link PhaseContext}
+ */
+ public void injectPhaseContext(PhaseContext context);
+}
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolver.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -12,8 +12,13 @@
import org.hibernate.hql.ast.resolve.path.FromClausePathResolutionStrategy;
import org.hibernate.hql.ast.resolve.path.OnFragmentPathResolutionStrategy;
import org.hibernate.hql.ast.resolve.path.WithFragmentPathResolutionStrategy;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.CollectionType;
import antlr.collections.AST;
@@ -218,6 +223,15 @@
return getPersisterReferenceBuilder().buildJoinNode( lhs, ( PersisterReference ) rhs,
joinType, null, false );
}
+ protected void injectSelectAlias(AST selectExpression, AST alias) {
+ ( ( SelectExpression ) selectExpression ).injectSelectAlias( alias.getText() );
+ }
+
+ protected void registerSelectExpression(AST selectExpression) {
+ log.debug( "registering select expression [" + selectExpression +
"]" );
+ super.registerSelectExpression( selectExpression );
+ }
+
protected void applyWithFragment(AST withFragment) {
log.debug( printer.showAsString( withFragment, "WITH fragment" ) );
WithFragmentPathResolutionStrategy strategy = ( WithFragmentPathResolutionStrategy )
pathResolutionStrategyStack.getCurrent();
@@ -251,4 +265,34 @@
}
return buffer.toString();
}
+
+ protected AST handleSelectedPropertyRef(AST propertyRef) {
+ if ( propertyRef.getType() == PROPERTY_REF ) {
+ PropertyReference ref = ( PropertyReference ) propertyRef;
+ Type propType = ref.getPropertyType();
+ String propName = ref.getPropertyName();
+ if ( propType.isAssociationType() ) {
+ // force the join (unless already joined) and mutate into a PERSISTER_REF_REF
node...
+ PersisterReference origin = ref.getOrigination();
+ JoinNode join = origin.locateReusableJoinByProperty( propName );
+ if ( join == null ) {
+ final PersisterReference rhs;
+ if ( propType.isEntityType() ) {
+ final String entityName = ( ( EntityType ) propType ).getAssociatedEntityName(
sessionFactory );
+ rhs = persisterReferenceBuilder.buildEntityPersisterReference( entityName, null,
false );
+ }
+ else if ( propType.isCollectionType() ) {
+ final String role = ( ( CollectionType ) propType ).getRole();
+ rhs = persisterReferenceBuilder.buildCollectionPersisterReference( role, null,
false );
+ }
+ else {
+ throw new HibernateException( "unexpected type [" + propType +
"]" );
+ }
+ join = persisterReferenceBuilder.buildJoinNode( origin, rhs, JoinType.INNER,
propName, false );
+ }
+ return astFactory.create( PERSISTER_REF_REF, join.getRhs().getAlias() );
+ }
+ }
+ return propertyRef;
+ }
}
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/HqlResolverASTFactory.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -4,7 +4,7 @@
import antlr.Token;
import org.hibernate.hql.ast.HqlASTFactory;
-import org.hibernate.hql.ast.tree.PhaseContextAwareNode;
+import org.hibernate.hql.ast.common.PhaseContextAwareNode;
import org.hibernate.hql.antlr.ResolveTokenTypes;
/**
@@ -39,6 +39,8 @@
return JoinNode.class;
case PROPERTY_REF:
return PropertyReference.class;
+ case PERSISTER_REF_REF:
+ return PersisterReferenceAliasReferenceNode.class;
}
return super.getASTNodeType( tokenType );
}
Modified: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinNode.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -4,6 +4,7 @@
import org.hibernate.hql.ast.tree.Node;
import org.hibernate.hql.ast.tree.DisplayableNode;
+import org.hibernate.hql.ast.common.JoinType;
/**
* Represents an HQL join. The coneptualization here is strictly that of
Deleted: branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/JoinType.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -1,62 +0,0 @@
-package org.hibernate.hql.ast.resolve;
-
-import java.io.Serializable;
-import java.util.HashMap;
-
-/**
- * Represents a canonical join type.
- * <p/>
- * Note that currently HQL really only supports inner and left outer joins
- * (though cross joins can also be achieved). This is because joins in HQL
- * are always defined in relation to a mapped association. However, when we
- * start allowing users to specify ad-hoc joins this may need to change to
- * allow the full spectrum of join types. Thus the others are provided here
- * currently just for completeness and for future expansion.
- *
- * @author Steve Ebersole
- */
-public class JoinType implements Serializable {
- /**
- * Represents an inner join.
- */
- public static final JoinType INNER = new JoinType( "inner" );
- /**
- * Represents a left outer join.
- */
- public static final JoinType LEFT = new JoinType( "left outer" );
- /**
- * Represents a right outer join.
- */
- public static final JoinType RIGHT = new JoinType( "right outer" );
- /**
- * Represents a cross join (aka a cartesian product).
- */
- public static final JoinType CROSS = new JoinType( "cross" );
- /**
- * Represents a full join.
- */
- public static final JoinType FULL = new JoinType( "full" );
-
- private static final HashMap INSTANCES = new HashMap();
- static {
- INSTANCES.put( INNER.name, INNER );
- INSTANCES.put( LEFT.name, LEFT );
- INSTANCES.put( RIGHT.name, RIGHT );
- INSTANCES.put( CROSS.name, CROSS );
- INSTANCES.put( FULL.name, FULL );
- }
-
- private final String name;
-
- private JoinType(String name) {
- this.name = name;
- }
-
- public String toString() {
- return name;
- }
-
- private Object readResolve() {
- return INSTANCES.get( name );
- }
-}
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceAliasReferenceNode.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -0,0 +1,43 @@
+package org.hibernate.hql.ast.resolve;
+
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.HibernateException;
+
+/**
+ * Represents a reference to a {@link PersisterReference}'s alias in another part of
+ * the HQL query...
+ *
+ * @author Steve Ebersole
+ */
+public class PersisterReferenceAliasReferenceNode extends Node implements
SelectExpression, PersisterReferenceContextAwareNode {
+ private PersisterReferenceContext persisterReferenceContext;
+ private String selectAlias;
+
+ private PersisterReference persisterReference;
+
+ public String getSelectAlias() {
+ return selectAlias;
+ }
+
+ public void injectSelectAlias(String selectAlias) {
+ this.selectAlias = selectAlias;
+ }
+
+ public PersisterReference getPersisterReference() {
+ if ( persisterReference == null ) {
+ if ( persisterReferenceContext == null ) {
+ throw new HibernateException( "PersisterReferenceContext not yet injected"
);
+ }
+ persisterReference = persisterReferenceContext.locatePersisterReferenceByAlias(
getPersisterReferenceAlias() );
+ }
+ return persisterReference;
+ }
+
+ public String getPersisterReferenceAlias() {
+ return getText();
+ }
+
+ public void injectPersisterReferenceContext(PersisterReferenceContext
persisterReferenceContext) {
+ this.persisterReferenceContext = persisterReferenceContext;
+ }
+}
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PersisterReferenceBuilder.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -5,6 +5,7 @@
import org.hibernate.MappingException;
import org.hibernate.hql.antlr.ResolveTokenTypes;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.persister.entity.EntityPersister;
/**
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/PropertyReference.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -15,21 +15,23 @@
*
* @author Steve Ebersole
*/
-public class PropertyReference extends Node implements
PersisterReferenceContextAwareNode, DisplayableNode {
+public class PropertyReference extends Node implements
PersisterReferenceContextAwareNode, DisplayableNode, SelectExpression {
private PersisterReferenceContext persisterContext;
+ private String alias;
+
// caches
- private String alias;
+ private String originationAlias;
private String propertyName;
private Type propertyType;
private PersisterReference origin;
public String getOriginationAlias() {
- if ( alias == null ) {
- alias = getFirstChild().getText();
+ if ( originationAlias == null ) {
+ originationAlias = getFirstChild().getText();
}
- return alias;
+ return originationAlias;
}
public String getPropertyName() {
@@ -63,4 +65,12 @@
public String getDisplayText() {
return " {origin=" + getOrigination().getText() + ", name=" +
getPropertyName() + ", type=" + getPropertyType().getName() + "}";
}
+
+ public void injectSelectAlias(String alias) {
+ this.alias = alias;
+ }
+
+ public String getSelectAlias() {
+ return alias;
+ }
}
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/SelectExpression.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -0,0 +1,11 @@
+package org.hibernate.hql.ast.resolve;
+
+/**
+ * Represents an atomic value in a select-clause value list.
+ *
+ * @author Steve Ebersole
+ */
+public interface SelectExpression {
+ public String getSelectAlias();
+ public void injectSelectAlias(String alias);
+}
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/BasicPathResolutionStrategySupport.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -7,7 +7,7 @@
import org.hibernate.hql.ast.resolve.PersisterReference;
import org.hibernate.hql.ast.resolve.PropertyReference;
import org.hibernate.hql.ast.resolve.JoinNode;
-import org.hibernate.hql.ast.resolve.JoinType;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.hql.ast.resolve.CollectionPersisterReference;
import org.hibernate.hql.CollectionProperties;
import org.hibernate.type.ComponentType;
@@ -114,7 +114,7 @@
}
- private class SimpleReferencePathPart extends PropertyPathPartAdapter {
+ protected class SimpleReferencePathPart extends PropertyPathPartAdapter {
public PropertyPathPart resolveIntermediatePathPart(String propertyName) {
throw new HibernateException( "cannot dereference simple value as part of path
expression" );
}
@@ -124,7 +124,7 @@
}
}
- private class ComponentReferencePathPart extends PropertyPathPartAdapter {
+ protected class ComponentReferencePathPart extends PropertyPathPartAdapter {
private final PersisterReference lhs;
private final String propertyPath;
private final ComponentType componentType;
@@ -163,7 +163,7 @@
}
}
- private class EntityReferencePathPart extends PropertyPathPartAdapter {
+ protected class EntityReferencePathPart extends PropertyPathPartAdapter {
private final PersisterReference lhs;
private final String propertyName;
@@ -201,7 +201,7 @@
}
}
- private class CollectionReferencePathPart extends PropertyPathPartAdapter {
+ protected class CollectionReferencePathPart extends PropertyPathPartAdapter {
private final PersisterReference lhs;
private final String propertyName;
Modified:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/FromClausePathResolutionStrategy.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -4,7 +4,7 @@
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;
import org.hibernate.HibernateException;
-import org.hibernate.hql.ast.resolve.JoinType;
+import org.hibernate.hql.ast.common.JoinType;
import org.hibernate.hql.ast.resolve.ResolutionContext;
import org.hibernate.hql.ast.resolve.PropertyReference;
import org.hibernate.hql.ast.resolve.PersisterReference;
Added:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/resolve/path/SelectClausePathResolutionStrategy.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -0,0 +1,17 @@
+package org.hibernate.hql.ast.resolve.path;
+
+import org.hibernate.hql.ast.resolve.ResolutionContext;
+
+/**
+ * Essentially the same stragety as {@link BasicPathResolutionStrategySupport}
+ * expcept that in the select clause an entity encountered as the terminal part
+ * must force a join...
+ *
+ * @author Steve Ebersole
+ */
+public class SelectClausePathResolutionStrategy extends
BasicPathResolutionStrategySupport {
+ protected SelectClausePathResolutionStrategy(ResolutionContext resolutionContext) {
+ super( resolutionContext );
+ }
+
+}
Deleted:
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/src/org/hibernate/hql/ast/tree/PhaseContextAwareNode.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -1,18 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.PhaseContext;
-
-/**
- * Injection service contract for nodes which require access to the current
- * phase context during their lifetime.
- *
- * @author Steve Ebersole
- */
-public interface PhaseContextAwareNode {
- /**
- * Inject a reference to the current {@link PhaseContext}.
- *
- * @param context The current {@link PhaseContext}
- */
- public void injectPhaseContext(PhaseContext context);
-}
Modified:
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java
===================================================================
---
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java 2006-12-19
19:08:27 UTC (rev 11003)
+++
branches/HQL_ANTLR_2/Hibernate3/test/org/hibernate/test/hql/redesign/ResolverTest.java 2006-12-19
22:22:21 UTC (rev 11004)
@@ -6,6 +6,8 @@
import org.hibernate.hql.ast.resolve.SelectStatementNode;
import org.hibernate.hql.ast.resolve.StatementNode;
import org.hibernate.hql.ast.resolve.HqlResolver;
+import org.hibernate.hql.ast.resolve.SelectExpression;
+import org.hibernate.hql.ast.resolve.PersisterReferenceBuilder;
import org.hibernate.hql.QuerySplitter;
import org.hibernate.hql.antlr.ResolveTokenTypes;
import org.hibernate.engine.SessionFactoryImplementor;
@@ -24,6 +26,8 @@
public class ResolverTest extends TestCase implements ResolveTokenTypes {
private static final ASTPrinter hqlrPrinter = generatePrinter();
+ public static final String CONSTANT = "constant-value";
+
private static ASTPrinter generatePrinter() {
ASTPrinter rtn = new ASTPrinter( ResolveTokenTypes.class );
rtn.setShowClassNames( false );
@@ -56,11 +60,62 @@
JoinCounter.assertJoinCount( 1, ast );
}
- public void testSelectExpression() throws Throwable {
- resolve( "select a from Animal a" );
- resolve( "select a.mother as m from Animal as a" );
+ public void testSelectPersisterReference() throws Throwable {
+ AST query = resolve( "select a from Animal a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.PERSISTER_REF_REF, selectExpression.getType() );
+ assertEquals( "a", selectExpression.getText() );
+ assertNull( ( ( SelectExpression ) selectExpression ).getSelectAlias() );
}
+ public void testSelectAssociationPropertyReference() throws Throwable {
+ AST query = resolve( "select a.mother as m from Animal as a" );
+ JoinCounter.assertJoinCount( 1, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.PERSISTER_REF_REF, selectExpression.getType() );
+ // this should work since there is only one non-explicit persister alias...
+ assertEquals( "<gen:0>", selectExpression.getText() );
+ assertEquals( "m", ( ( SelectExpression ) selectExpression ).getSelectAlias()
);
+ }
+
+ public void testSimpleSimplePropertyReference() throws Throwable {
+ AST query = resolve( "select a.name as m from Animal as a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.PROPERTY_REF, selectExpression.getType() );
+ assertEquals( "a.name", selectExpression.getText() );
+ assertEquals( "m", ( ( SelectExpression ) selectExpression ).getSelectAlias()
);
+ }
+
+ public void testSelectPropertyRefCount() throws Throwable {
+ AST query = resolve( "select count(a.mother) from Animal as a" );
+ JoinCounter.assertJoinCount( 0, query );
+ SelectExpressionCounter.assertSelectExpressionCount( 1, query );
+ assertTrue( query instanceof SelectStatementNode );
+ AST selectClause = query.getFirstChild().getFirstChild().getNextSibling();
+ assertNotNull( selectClause );
+ assertEquals( ResolveTokenTypes.SELECT_CLAUSE, selectClause.getType() );
+ AST selectExpression = selectClause.getFirstChild();
+ assertEquals( ResolveTokenTypes.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 SelectStatementNode );
@@ -173,16 +228,34 @@
}
}
public static void assertJoinCount(int expected, AST tree) {
- org.hibernate.test.hql.redesign.ResolverTest.JoinCounter.assertJoinCount(
"incorrect join count", expected, tree );
+ JoinCounter.assertJoinCount( "incorrect join count", expected, tree );
}
public static void assertJoinCount(String failMessage, int expected, AST tree) {
- org.hibernate.test.hql.redesign.ResolverTest.JoinCounter counter = new
org.hibernate.test.hql.redesign.ResolverTest.JoinCounter();
+ JoinCounter counter = new JoinCounter();
NodeTraverser walker = new NodeTraverser( counter );
walker.traverseDepthFirst( tree );
assertEquals( failMessage, expected, counter.count );
}
}
+ private static class SelectExpressionCounter implements NodeTraverser.VisitationStrategy
{
+ int count;
+ public void visit(AST node) {
+ if ( node instanceof SelectExpression ) {
+ count++;
+ }
+ }
+ public static void assertSelectExpressionCount(int expected, AST tree) {
+ SelectExpressionCounter.assertSelectExpressionCount( "incorrect select expression
count", expected, tree );
+ }
+ public static void assertSelectExpressionCount(String failMessage, int expected, AST
tree) {
+ SelectExpressionCounter counter = new SelectExpressionCounter();
+ NodeTraverser walker = new NodeTraverser( counter );
+ walker.traverseDepthFirst( tree );
+ assertEquals( failMessage, expected, counter.count );
+ }
+ }
+
public static Test suite() {
return new TestSuite(org.hibernate.test.hql.redesign.ResolverTest.class);
}