FileDocCategorySizeDatePackage
SqlGenerator.javaAPI DocHibernate 3.2.57333Tue Jun 27 21:53:40 BST 2006org.hibernate.hql.ast

SqlGenerator

public class SqlGenerator extends org.hibernate.hql.antlr.SqlGeneratorBase implements ErrorReporter
Generates SQL by overriding callback methods in the base class, which does the actual SQL AST walking.
author
Joshua Davis
author
Steve Ebersole

Fields Summary
private ParseErrorHandler
parseErrorHandler
Handles parser errors.
private SqlWriter
writer
all append invocations on the buf should go through this Output instance variable. The value of this variable may be temporarily substitued by sql function processing code to catch generated arguments. This is because sql function templates need arguments as seperate string chunks that will be assembled into the target dialect-specific function call.
private org.hibernate.engine.SessionFactoryImplementor
sessionFactory
private LinkedList
outputStack
Constructors Summary
public SqlGenerator(org.hibernate.engine.SessionFactoryImplementor sfi)

		super();
		parseErrorHandler = new ErrorCounter();
		sessionFactory = sfi;
	
Methods Summary
protected voidbeginFunctionTemplate(antlr.collections.AST m, antlr.collections.AST i)

		MethodNode methodNode = ( MethodNode ) m;
		SQLFunction template = methodNode.getSQLFunction();
		if ( template == null ) {
			// if template is null we just write the function out as it appears in the hql statement
			super.beginFunctionTemplate( m, i );
		}
		else {
			// this function has a template -> redirect output and catch the arguments
			outputStack.addFirst( writer );
			writer = new FunctionArguments();
		}
	
protected voidcommaBetweenParameters(java.lang.String comma)

		writer.commaBetweenParameters( comma );
	
protected voidendFunctionTemplate(antlr.collections.AST m)

		MethodNode methodNode = ( MethodNode ) m;
		SQLFunction template = methodNode.getSQLFunction();
		if ( template == null ) {
			super.endFunctionTemplate( m );
		}
		else {
			// this function has a template -> restore output, apply the template and write the result out
			FunctionArguments functionArguments = ( FunctionArguments ) writer;   // TODO: Downcast to avoid using an interface?  Yuck.
			writer = ( SqlWriter ) outputStack.removeFirst();
			out( template.render( functionArguments.getArgs(), sessionFactory ) );
		}
	
protected voidfromFragmentSeparator(antlr.collections.AST a)

		// check two "adjecent" nodes at the top of the from-clause tree
		AST next = a.getNextSibling();
		if ( next == null || !hasText( a ) ) {
			return;
		}

		FromElement left = ( FromElement ) a;
		FromElement right = ( FromElement ) next;

		///////////////////////////////////////////////////////////////////////
		// HACK ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!
		// Attempt to work around "ghost" ImpliedFromElements that occasionally
		// show up between the actual things being joined.  This consistently
		// occurs from index nodes (at least against many-to-many).  Not sure
		// if there are other conditions
		//
		// Essentially, look-ahead to the next FromElement that actually
		// writes something to the SQL
		while ( right != null && !hasText( right ) ) {
			right = ( FromElement ) right.getNextSibling();
		}
		if ( right == null ) {
			return;
		}
		///////////////////////////////////////////////////////////////////////

		if ( !hasText( right ) ) {
			return;
		}

		if ( right.getRealOrigin() == left ||
		     ( right.getRealOrigin() != null && right.getRealOrigin() == left.getRealOrigin() ) ) {
			// right represents a joins originating from left; or
			// both right and left reprersent joins originating from the same FromElement
			if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) {
				out( ", " );
			}
			else {
				out( " " );
			}
		}
		else {
			// these are just two unrelated table references
			out( ", " );
		}
	
public ParseErrorHandlergetParseErrorHandler()

		return parseErrorHandler;
	
public java.lang.StringgetSQL()

		return getStringBuffer().toString();
	
protected voidnestedFromFragment(antlr.collections.AST d, antlr.collections.AST parent)

		// check a set of parent/child nodes in the from-clause tree
		// to determine if a comma is required between them
		if ( d != null && hasText( d ) ) {
			if ( parent != null && hasText( parent ) ) {
				// again, both should be FromElements
				FromElement left = ( FromElement ) parent;
				FromElement right = ( FromElement ) d;
				if ( right.getRealOrigin() == left ) {
					// right represents a joins originating from left...
					if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) {
						out( ", " );
					}
					else {
						out( " " );
					}
				}
				else {
					// not so sure this is even valid subtree.  but if it was, it'd
					// represent two unrelated table references...
					out( ", " );
				}
			}
			out( d );
		}
	
protected voidoptionalSpace()

		int c = getLastChar();
		switch ( c ) {
			case -1:
				return;
			case ' ":
				return;
			case ')":
				return;
			case '(":
				return;
			default:
				out( " " );
		}
	
protected voidout(java.lang.String s)


	    
		writer.clause( s );
	
protected voidout(antlr.collections.AST n)

		if ( n instanceof Node ) {
			out( ( ( Node ) n ).getRenderText( sessionFactory ) );
		}
		else {
			super.out( n );
		}
	
public static voidpanic()

		throw new QueryException( "TreeWalker: panic" );
	
public voidreportError(antlr.RecognitionException e)

		parseErrorHandler.reportError( e ); // Use the delegate.
	
public voidreportError(java.lang.String s)

		parseErrorHandler.reportError( s ); // Use the delegate.
	
public voidreportWarning(java.lang.String s)

		parseErrorHandler.reportWarning( s );