void CreateFromJoinElement( IASTNode path, IASTNode alias, int joinType, IASTNode fetchNode, IASTNode propertyFetch, IASTNode with) { bool fetch = fetchNode != null; if ( fetch && IsSubQuery ) { throw new QueryException( "fetch not allowed in subquery from-elements" ); } // The path AST should be a DotNode, and it should have been evaluated already. if ( path.Type != DOT ) { throw new SemanticException( "Path expected for join!" ); } DotNode dot = ( DotNode ) path; //JoinType hibernateJoinType = JoinProcessor.ToHibernateJoinType( joinType ); JoinType hibernateJoinType = _impliedJoinType; dot.JoinType = hibernateJoinType; // Tell the dot node about the join type. dot.Fetch = fetch; // Generate an explicit join for the root dot node. The implied joins will be collected and passed up // to the root dot node. dot.Resolve( true, false, alias == null ? null : alias.Text ); FromElement fromElement; if (dot.DataType != null && dot.DataType.IsComponentType) { var factory = new FromElementFactory(CurrentFromClause, dot.GetLhs().FromElement, dot.PropertyPath, alias == null ? null : alias.Text, null, false); fromElement = factory.CreateComponentJoin((ComponentType) dot.DataType); } else { fromElement = dot.GetImpliedJoin(); if (fromElement == null) { throw new InvalidPathException("Invalid join: " + dot.Path); } fromElement.SetAllPropertyFetch(propertyFetch != null); if (with != null) { if (fetch) { throw new SemanticException("with-clause not allowed on fetched associations; use filters"); } HandleWithFragment(fromElement, with); } } if ( log.IsDebugEnabled ) { log.Debug( "createFromJoinElement() : " + _printer.ShowAsString( fromElement, "-- join tree --" ) ); } }