@@ -804,111 +804,114 @@ protected String expandParameterLists() {
804804 }
805805 // HHH-1123
806806 // Some DBs limit number of IN expressions. For now, warn...
807- final SessionFactoryImplementor sessionFactory = getSessionFactory ();
808- final Dialect dialect = sessionFactory .getJdbcServices ().getDialect ();
809- final boolean paddingEnabled = sessionFactory .getSessionFactoryOptions ().inClauseParameterPaddingEnabled ();
807+ final SessionFactoryImplementor factory = getSessionFactory ();
808+ final Dialect dialect = factory .getJdbcServices ().getDialect ();
809+ final boolean paddingEnabled = factory .getSessionFactoryOptions ().inClauseParameterPaddingEnabled ();
810810 final int inExprLimit = dialect .getInExpressionCountLimit ();
811811
812- StringBuilder sb = null ;
812+ StringBuilder sql = null ;
813813
814814 // Handle parameter lists
815815 int offset = 0 ;
816816 for ( ParameterOccurrence occurrence : parameterOccurrences ) {
817- final QueryParameterImplementor <?> queryParameter = occurrence .getParameter ();
817+ final QueryParameterImplementor <?> queryParameter = occurrence .parameter ();
818818 final QueryParameterBinding <?> binding = parameterBindings .getBinding ( queryParameter );
819- if ( !binding .isMultiValued () ) {
820- continue ;
821- }
822- final Collection <?> bindValues = binding .getBindValues ();
823-
824- final int bindValueCount = bindValues .size ();
825- final int bindValueMaxCount = determineBindValueMaxCount ( paddingEnabled , inExprLimit , bindValueCount );
826-
827- if ( inExprLimit > 0 && bindValueCount > inExprLimit ) {
828- log .tooManyInExpressions (
829- dialect .getClass ().getName (),
830- inExprLimit ,
831- queryParameter .getName () == null
832- ? queryParameter .getPosition ().toString ()
833- : queryParameter .getName (),
834- bindValueCount
835- );
836- }
837-
838- final int sourcePosition = occurrence .getSourcePosition ();
839- if ( sourcePosition < 0 ) {
840- continue ;
841- }
842-
843- // check if placeholder is already immediately enclosed in parentheses
844- // (ignoring whitespace)
845- boolean isEnclosedInParens = true ;
846- for ( int i = sourcePosition - 1 ; i >= 0 ; i -- ) {
847- final char ch = sqlString .charAt ( i );
848- if ( !isWhitespace ( ch ) ) {
849- isEnclosedInParens = ch == '(' ;
850- break ;
851- }
852- }
853- if ( isEnclosedInParens ) {
854- for ( int i = sourcePosition + 1 ; i < sqlString .length (); i ++ ) {
855- final char ch = sqlString .charAt ( i );
856- if ( !isWhitespace ( ch ) ) {
857- isEnclosedInParens = ch == ')' ;
858- break ;
819+ if ( binding .isMultiValued () ) {
820+ final int bindValueCount = binding .getBindValues ().size ();
821+ logTooManyExpressions ( inExprLimit , bindValueCount , dialect , queryParameter );
822+ final int sourcePosition = occurrence .sourcePosition ();
823+ if ( sourcePosition >= 0 ) {
824+ // check if placeholder is already immediately enclosed in parentheses
825+ // (ignoring whitespace)
826+ final boolean isEnclosedInParens = isEnclosedInParens ( sourcePosition );
827+ // short-circuit for performance when only 1 value and the
828+ // placeholder is already enclosed in parentheses...
829+ if ( bindValueCount != 1 || !isEnclosedInParens ) {
830+ if ( sql == null ) {
831+ sql = new StringBuilder ( sqlString .length () + 20 );
832+ sql .append ( sqlString );
833+ }
834+ final int bindValueMaxCount =
835+ determineBindValueMaxCount ( paddingEnabled , inExprLimit , bindValueCount );
836+ final String expansionListAsString =
837+ expandList ( bindValueMaxCount , isEnclosedInParens );
838+ final int start = sourcePosition + offset ;
839+ final int end = start + 1 ;
840+ sql .replace ( start , end , expansionListAsString );
841+ offset += expansionListAsString .length () - 1 ;
859842 }
860843 }
861844 }
845+ }
846+ return sql == null ? sqlString : sql .toString ();
847+ }
848+
849+ private static void logTooManyExpressions (
850+ int inExprLimit , int bindValueCount ,
851+ Dialect dialect , QueryParameterImplementor <?> queryParameter ) {
852+ if ( inExprLimit > 0 && bindValueCount > inExprLimit ) {
853+ log .tooManyInExpressions (
854+ dialect .getClass ().getName (),
855+ inExprLimit ,
856+ queryParameter .getName () == null
857+ ? queryParameter .getPosition ().toString ()
858+ : queryParameter .getName (),
859+ bindValueCount
860+ );
861+ }
862+ }
862863
863- if ( bindValueCount == 1 && isEnclosedInParens ) {
864- // short-circuit for performance when only 1 value and the
865- // placeholder is already enclosed in parentheses...
866- continue ;
864+ private static String expandList (int bindValueMaxCount , boolean isEnclosedInParens ) {
865+ // HHH-8901
866+ if ( bindValueMaxCount == 0 ) {
867+ return isEnclosedInParens ? "null" : "(null)" ;
868+ }
869+ else {
870+ // Shift 1 bit instead of multiplication by 2
871+ final char [] chars ;
872+ if ( isEnclosedInParens ) {
873+ chars = new char [(bindValueMaxCount << 1 ) - 1 ];
874+ chars [0 ] = '?' ;
875+ for ( int i = 1 ; i < bindValueMaxCount ; i ++ ) {
876+ final int index = i << 1 ;
877+ chars [index - 1 ] = ',' ;
878+ chars [index ] = '?' ;
879+ }
867880 }
868-
869- if ( sb == null ) {
870- sb = new StringBuilder ( sqlString .length () + 20 );
871- sb .append ( sqlString );
881+ else {
882+ chars = new char [(bindValueMaxCount << 1 ) + 1 ];
883+ chars [0 ] = '(' ;
884+ chars [1 ] = '?' ;
885+ for ( int i = 1 ; i < bindValueMaxCount ; i ++ ) {
886+ final int index = i << 1 ;
887+ chars [index ] = ',' ;
888+ chars [index + 1 ] = '?' ;
889+ }
890+ chars [chars .length - 1 ] = ')' ;
872891 }
892+ return new String ( chars );
893+ }
894+ }
873895
874- final String expansionListAsString ;
875- // HHH-8901
876- if ( bindValueMaxCount == 0 ) {
877- expansionListAsString = isEnclosedInParens ? "null" : "(null)" ;
896+ private boolean isEnclosedInParens (int sourcePosition ) {
897+ boolean isEnclosedInParens = true ;
898+ for ( int i = sourcePosition - 1 ; i >= 0 ; i -- ) {
899+ final char ch = sqlString .charAt ( i );
900+ if ( !isWhitespace ( ch ) ) {
901+ isEnclosedInParens = ch == '(' ;
902+ break ;
878903 }
879- else {
880- // Shift 1 bit instead of multiplication by 2
881- final char [] chars ;
882- if ( isEnclosedInParens ) {
883- chars = new char [( bindValueMaxCount << 1 ) - 1 ];
884- chars [0 ] = '?' ;
885- for ( int i = 1 ; i < bindValueMaxCount ; i ++ ) {
886- final int index = i << 1 ;
887- chars [index - 1 ] = ',' ;
888- chars [index ] = '?' ;
889- }
890- }
891- else {
892- chars = new char [( bindValueMaxCount << 1 ) + 1 ];
893- chars [0 ] = '(' ;
894- chars [1 ] = '?' ;
895- for ( int i = 1 ; i < bindValueMaxCount ; i ++ ) {
896- final int index = i << 1 ;
897- chars [index ] = ',' ;
898- chars [index + 1 ] = '?' ;
899- }
900- chars [chars .length - 1 ] = ')' ;
904+ }
905+ if ( isEnclosedInParens ) {
906+ for ( int i = sourcePosition + 1 ; i < sqlString .length (); i ++ ) {
907+ final char ch = sqlString .charAt ( i );
908+ if ( !isWhitespace ( ch ) ) {
909+ isEnclosedInParens = ch == ')' ;
910+ break ;
901911 }
902-
903- expansionListAsString = new String (chars );
904912 }
905-
906- final int start = sourcePosition + offset ;
907- final int end = start + 1 ;
908- sb .replace ( start , end , expansionListAsString );
909- offset += expansionListAsString .length () - 1 ;
910913 }
911- return sb == null ? sqlString : sb . toString () ;
914+ return isEnclosedInParens ;
912915 }
913916
914917 public static int determineBindValueMaxCount (boolean paddingEnabled , int inExprLimit , int bindValueCount ) {
0 commit comments