HHH-9100 - Improve CAST function support

(cherry picked from commit 137c2daf81)

Conflicts:
	hibernate-core/src/main/java/org/hibernate/hql/internal/ast/SqlGenerator.java
This commit is contained in:
Steve Ebersole 2014-04-08 13:03:40 -04:00 committed by Brett Meyer
parent 6cef805a32
commit cfc0327637
4 changed files with 48 additions and 24 deletions

View File

@ -628,7 +628,7 @@ functionCall
processFunction( #functionCall, inSelect ); processFunction( #functionCall, inSelect );
inFunctionCall=false; inFunctionCall=false;
} }
| #(CAST {inFunctionCall=true;} expr pathAsIdent) { | #(CAST {inFunctionCall=true;} exprOrSubquery pathAsIdent) {
processCastFunction( #functionCall, inSelect ); processCastFunction( #functionCall, inSelect );
inFunctionCall=false; inFunctionCall=false;
} }

View File

@ -92,8 +92,8 @@ options {
out(")"); out(")");
} }
protected void commaBetweenParameters(String comma) { protected void betweenFunctionArguments() {
out(comma); out( ", " );
} }
protected void captureExpressionStart() { protected void captureExpressionStart() {
@ -465,11 +465,15 @@ methodCall
: #(m:METHOD_CALL i:METHOD_NAME { beginFunctionTemplate(m,i); } : #(m:METHOD_CALL i:METHOD_NAME { beginFunctionTemplate(m,i); }
( #(EXPR_LIST (arguments)? ) )? ( #(EXPR_LIST (arguments)? ) )?
{ endFunctionTemplate(m); } ) { endFunctionTemplate(m); } )
| #( c:CAST { beginFunctionTemplate(c,c); } expr castTargetType { endFunctionTemplate(c); } ) | #( c:CAST { beginFunctionTemplate(c,c); } castExpression {betweenFunctionArguments();} castTargetType { endFunctionTemplate(c); } )
; ;
arguments arguments
: expr ( { commaBetweenParameters(", "); } expr )* : expr ( { betweenFunctionArguments(); } expr )*
;
castExpression
: selectExpr
; ;
castTargetType castTargetType

View File

@ -54,7 +54,7 @@ public class CastFunction implements SQLFunction {
public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException { public String render(Type columnType, List args, SessionFactoryImplementor factory) throws QueryException {
if ( args.size()!=2 ) { if ( args.size()!=2 ) {
throw new QueryException("cast() requires two arguments"); throw new QueryException( "cast() requires two arguments; found : " + args.size() );
} }
String type = (String) args.get(1); String type = (String) args.get(1);
int[] sqlTypeCodes = factory.getTypeResolver().heuristicType(type).sqlTypes(factory); int[] sqlTypeCodes = factory.getTypeResolver().heuristicType(type).sqlTypes(factory);

View File

@ -43,6 +43,7 @@ import org.hibernate.hql.internal.ast.tree.ParameterNode;
import org.hibernate.hql.internal.ast.util.ASTPrinter; import org.hibernate.hql.internal.ast.util.ASTPrinter;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.StringHelper;
import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.param.ParameterSpecification; import org.hibernate.param.ParameterSpecification;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
@ -138,8 +139,8 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
} }
@Override @Override
protected void commaBetweenParameters(String comma) { protected void betweenFunctionArguments() {
writer.commaBetweenParameters( comma ); writer.betweenFunctionArguments();
} }
@Override @Override
@ -234,14 +235,7 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
interface SqlWriter { interface SqlWriter {
void clause(String clause); void clause(String clause);
/** void betweenFunctionArguments();
* todo remove this hack
* The parameter is either ", " or " , ". This is needed to pass sql generating tests as the old
* sql generator uses " , " in the WHERE and ", " in SELECT.
*
* @param comma either " , " or ", "
*/
void commaBetweenParameters(String comma);
} }
interface FunctionArgumentsCollectingWriter extends SqlWriter { interface FunctionArgumentsCollectingWriter extends SqlWriter {
@ -265,7 +259,8 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
} }
} }
public void commaBetweenParameters(String comma) { @Override
public void betweenFunctionArguments() {
++argInd; ++argInd;
} }
@ -279,20 +274,44 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
* which catches function arguments. * which catches function arguments.
*/ */
class CastFunctionArguments implements FunctionArgumentsCollectingWriter { class CastFunctionArguments implements FunctionArgumentsCollectingWriter {
private final List<String> args = new ArrayList<String>( 3 ); private String castExpression;
private String castTargetType;
private boolean startedType;
@Override @Override
public void clause(String clause) { public void clause(String clause) {
args.add( clause ); if ( startedType ) {
if ( castTargetType == null ) {
castTargetType = clause;
}
else {
castTargetType += clause;
}
}
else {
if ( castExpression == null ) {
castExpression = clause;
}
else {
castExpression += clause;
}
}
} }
@Override @Override
public void commaBetweenParameters(String comma) { public void betweenFunctionArguments() {
// todo : should this be an exception? Its not likely to end well if this method is called here... if ( startedType ) {
throw new QueryException( "CAST function should only have 2 arguments" );
}
startedType = true;
} }
public List getArgs() { public List getArgs() {
return args; List<String> rtn = CollectionHelper.arrayList( 2 );
rtn.add( castExpression );
rtn.add( castTargetType );
return rtn;
} }
} }
@ -304,8 +323,9 @@ public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
getStringBuilder().append( clause ); getStringBuilder().append( clause );
} }
public void commaBetweenParameters(String comma) { @Override
getStringBuilder().append( comma ); public void betweenFunctionArguments() {
getStringBuilder().append( ", " );
} }
} }