2727import org .hibernate .type .JavaObjectType ;
2828import org .hibernate .type .descriptor .java .JavaType ;
2929import org .hibernate .type .descriptor .java .spi .JdbcTypeRecommendationException ;
30+ import org .hibernate .type .descriptor .jdbc .JdbcType ;
3031import org .hibernate .type .descriptor .jdbc .JdbcTypeIndicators ;
3132import org .hibernate .type .spi .TypeConfiguration ;
3233
@@ -103,7 +104,7 @@ public void validate(
103104 switch (type ) {
104105 case TEMPORAL_UNIT :
105106 if ( !(argument instanceof SqmExtractUnit ) && !(argument instanceof SqmDurationUnit ) ) {
106- throwError (type , Object .class , functionName , count );
107+ throwError (type , Object .class , null , functionName , count );
107108 }
108109 break ;
109110 // the following are not really necessary for the functions we have today
@@ -112,12 +113,12 @@ public void validate(
112113 // something crazy by the parser
113114 case TRIM_SPEC :
114115 if ( !(argument instanceof SqmTrimSpecification ) ) {
115- throwError (type , Object .class , functionName , count );
116+ throwError (type , Object .class , null , functionName , count );
116117 }
117118 break ;
118119 case COLLATION :
119120 if ( !(argument instanceof SqmCollation ) ) {
120- throwError (type , Object .class , functionName , count );
121+ throwError (type , Object .class , null , functionName , count );
121122 }
122123 break ;
123124 case NO_UNTYPED :
@@ -149,9 +150,11 @@ private void checkArgumentType(
149150 if ( !isUnknown ( javaType ) ) {
150151 DomainType <?> domainType = argument .getExpressible ().getSqmType ();
151152 if ( domainType instanceof JdbcMapping ) {
153+ JdbcType jdbcType = ((JdbcMapping ) domainType ).getJdbcType ();
152154 checkArgumentType (
153155 count , functionName , type ,
154- ((JdbcMapping ) domainType ).getJdbcType ().getDefaultSqlTypeCode (),
156+ jdbcType .getDefaultSqlTypeCode (),
157+ jdbcType .getFriendlyName (),
155158 javaType .getJavaTypeClass ()
156159 );
157160 }
@@ -161,6 +164,7 @@ private void checkArgumentType(
161164 checkArgumentType (
162165 count , functionName , type ,
163166 getJdbcType ( indicators , javaType ),
167+ null ,
164168 javaType .getJavaTypeClass ()
165169 );
166170 }
@@ -229,14 +233,16 @@ private int validateArgument(int paramNumber, JdbcMappingContainer expressionTyp
229233 functionName ,
230234 type ,
231235 mapping .getJdbcType ().getDefaultSqlTypeCode (),
236+ mapping .getJdbcType ().getFriendlyName (),
232237 mapping .getJavaTypeDescriptor ().getJavaType ()
233238 );
234239 }
235240 }
236241 return paramNumber ;
237242 }
238243
239- private static void checkArgumentType (int paramNumber , String functionName , FunctionParameterType type , int code , Type javaType ) {
244+ private static void checkArgumentType (
245+ int paramNumber , String functionName , FunctionParameterType type , int code , String sqlType , Type javaType ) {
240246 switch (type ) {
241247 case COMPARABLE :
242248 if ( !isCharacterType (code ) && !isTemporalType (code ) && !isNumericType (code ) && !isEnumType ( code )
@@ -246,68 +252,83 @@ private static void checkArgumentType(int paramNumber, String functionName, Func
246252 // as a special case, we consider a binary column
247253 // comparable when it is mapped by a Java UUID
248254 && !( javaType == java .util .UUID .class && code == Types .BINARY ) ) {
249- throwError (type , javaType , functionName , paramNumber );
255+ throwError (type , javaType , sqlType , functionName , paramNumber );
250256 }
251257 break ;
252258 case STRING :
253259 if ( !isCharacterType (code ) && !isEnumType (code ) ) {
254- throwError (type , javaType , functionName , paramNumber );
260+ throwError (type , javaType , sqlType , functionName , paramNumber );
255261 }
256262 break ;
257263 case STRING_OR_CLOB :
258264 if ( !isCharacterOrClobType (code ) ) {
259- throwError (type , javaType , functionName , paramNumber );
265+ throwError (type , javaType , sqlType , functionName , paramNumber );
260266 }
261267 break ;
262268 case NUMERIC :
263269 if ( !isNumericType (code ) ) {
264- throwError (type , javaType , functionName , paramNumber );
270+ throwError (type , javaType , sqlType , functionName , paramNumber );
265271 }
266272 break ;
267273 case INTEGER :
268274 if ( !isIntegral (code ) ) {
269- throwError (type , javaType , functionName , paramNumber );
275+ throwError (type , javaType , sqlType , functionName , paramNumber );
270276 }
271277 break ;
272278 case BOOLEAN :
273279 // ugh, need to be careful here, need to accept all the
274280 // JDBC type codes that a Dialect might use for BOOLEAN
275281 if ( code != BOOLEAN && code != BIT && code != TINYINT && code != SMALLINT ) {
276- throwError (type , javaType , functionName , paramNumber );
282+ throwError (type , javaType , sqlType , functionName , paramNumber );
277283 }
278284 break ;
279285 case TEMPORAL :
280286 if ( !isTemporalType (code ) ) {
281- throwError (type , javaType , functionName , paramNumber );
287+ throwError (type , javaType , sqlType , functionName , paramNumber );
282288 }
283289 break ;
284290 case DATE :
285291 if ( !hasDatePart (code ) ) {
286- throwError (type , javaType , functionName , paramNumber );
292+ throwError (type , javaType , sqlType , functionName , paramNumber );
287293 }
288294 break ;
289295 case TIME :
290296 if ( !hasTimePart (code ) ) {
291- throwError (type , javaType , functionName , paramNumber );
297+ throwError (type , javaType , sqlType , functionName , paramNumber );
292298 }
293299 break ;
294300 case SPATIAL :
295301 if ( !isSpatialType ( code ) ) {
296- throwError ( type , javaType , functionName , paramNumber );
302+ throwError ( type , javaType , sqlType , functionName , paramNumber );
297303 }
298304 }
299305 }
300306
301- private static void throwError (FunctionParameterType type , Type javaType , String functionName , int paramNumber ) {
302- throw new FunctionArgumentException (
303- String .format (
304- "Parameter %d of function '%s()' has type '%s', but argument is of type '%s'" ,
305- paramNumber ,
306- functionName ,
307- type ,
308- javaType .getTypeName ()
309- )
310- );
307+ private static void throwError (
308+ FunctionParameterType type , Type javaType , String sqlType , String functionName , int paramNumber ) {
309+ if ( sqlType == null ) {
310+ throw new FunctionArgumentException (
311+ String .format (
312+ "Parameter %d of function '%s()' has type '%s', but argument is of type '%s'" ,
313+ paramNumber ,
314+ functionName ,
315+ type ,
316+ javaType .getTypeName ()
317+ )
318+ );
319+ }
320+ else {
321+ throw new FunctionArgumentException (
322+ String .format (
323+ "Parameter %d of function '%s()' has type '%s', but argument is of type '%s' mapped to '%s'" ,
324+ paramNumber ,
325+ functionName ,
326+ type ,
327+ javaType .getTypeName (),
328+ sqlType
329+ )
330+ );
331+ }
311332 }
312333
313334 @ Override
0 commit comments