1010import java .io .InputStream ;
1111import java .io .Reader ;
1212import java .math .BigDecimal ;
13- import java .math .RoundingMode ;
1413import java .net .MalformedURLException ;
1514import java .net .URL ;
1615import java .sql .Array ;
3029import java .sql .Statement ;
3130import java .sql .Time ;
3231import java .sql .Timestamp ;
33- import java .time .ZonedDateTime ;
3432import java .util .Arrays ;
3533import java .util .Calendar ;
3634import java .util .List ;
@@ -52,7 +50,7 @@ public class ArrayResultSet implements ResultSet {
5250 private int fetchDirection = ResultSet .FETCH_FORWARD ;
5351 private int fetchSize = 0 ;
5452 private boolean wasNull = false ;
55- private final Map <Class <?>, Function <Object , Object >> converterMap ;
53+ private Map <Class <?>, Function <Object , Object >> converterMap ;
5654 private final Map <Class <?>, Function <Object , Object >> indexConverterMap ;
5755 private final ClickHouseDataType componentDataType ;
5856 private final Class <?> defaultClass ;
@@ -74,16 +72,6 @@ public ArrayResultSet(Object array, ClickHouseColumn column) {
7472 this .componentDataType = valueColumn .getDataType ();
7573 this .defaultClass = JdbcUtils .DATA_TYPE_CLASS_MAP .get (componentDataType );
7674 indexConverterMap = defaultValueConverters .getConvertersForType (Integer .class );
77- if (this .length > 0 ) {
78- Class <?> itemClass = array .getClass ().getComponentType ();
79- if (itemClass == null ) {
80- itemClass = java .lang .reflect .Array .get (array , 0 ).getClass ();
81- }
82- converterMap = defaultValueConverters .getConvertersForType (itemClass );
83- } else {
84- // empty array - no values to convert
85- converterMap = null ;
86- }
8775 }
8876
8977 @ Override
@@ -107,39 +95,58 @@ private void checkRowPosition() throws SQLException {
10795 }
10896 }
10997
98+ private Map <Class <?>, Function <Object , Object >> initValueConverterMapIfNeeded (Object nonNullValue ) {
99+ if (converterMap == null ) {
100+ if (array .getClass ().getComponentType () == Object .class ) {
101+ converterMap = defaultValueConverters .getConvertersForType (nonNullValue .getClass ());
102+ } else {
103+ converterMap = defaultValueConverters .getConvertersForType (array .getClass ().getComponentType ());
104+ }
105+ }
106+ return converterMap ;
107+ }
108+
109+ private Object convertValue (Object value , Class <?> targetType , Map <Class <?>, Function <Object , Object >> valueConverterMap ) throws SQLException {
110+ if (value == null || targetType == value .getClass () || targetType == Object .class ) {
111+ return value ;
112+ }
113+
114+ Function <Object , Object > converter = valueConverterMap .get (targetType );
115+ if (converter != null ) {
116+ try {
117+ return converter .apply (value );
118+ } catch (Exception e ) {
119+ throw new SQLException ("Failed to convert value of " + value .getClass () + " to " + targetType ,
120+ ExceptionUtils .SQL_STATE_DATA_EXCEPTION , e );
121+ }
122+ } else {
123+ throw new SQLException ("Value of " + value .getClass () + " cannot be converted to " + targetType );
124+ }
125+ }
126+
110127 private Object getValueAsObject (int columnIndex , Class <?> type , Object defaultValue ) throws SQLException {
111128 checkColumnIndex (columnIndex );
112129 checkRowPosition ();
113130
114- Object value ;
115- Map <Class <?>, Function <Object , Object >> valueConverterMap ;
116131 if (columnIndex == 1 ) {
117- value = pos + 1 ;
118- valueConverterMap = indexConverterMap ;
132+ Integer value = pos + 1 ;
133+ return convertValue ( value , type , indexConverterMap ) ;
119134 } else {
120- value = java .lang .reflect .Array .get (array , pos );
121- valueConverterMap = converterMap ;
122- }
135+ Object value = java .lang .reflect .Array .get (array , pos );
136+ wasNull = value == null ;
137+ if (value == null ) {
138+ return defaultValue ;
139+ }
123140
124- if (columnIndex != 1 && value != null && type == Array .class ) {
125- ClickHouseColumn nestedColumn = column .getArrayNestedLevel () == 1 ? column .getArrayBaseColumn () : column .getNestedColumns ().get (0 );
126- return new com .clickhouse .jdbc .types .Array (nestedColumn , JdbcUtils .arrayToObjectArray (value ));
127- } else if (value != null && type != Object .class ) {
128- // if there is something to convert. type == Object.class means no conversion
129- Function <Object , Object > converter = valueConverterMap .get (type );
130- if (converter != null ) {
131- try {
132- value = converter .apply (value );
133- } catch (Exception e ) {
134- throw new SQLException ("Failed to convert value of " + value .getClass () + " to " + type ,
135- ExceptionUtils .SQL_STATE_DATA_EXCEPTION , e );
136- }
141+ if (type == Array .class ) {
142+ ClickHouseColumn nestedColumn =
143+ column .getArrayNestedLevel () == 1 ? column .getArrayBaseColumn () : column .getNestedColumns ().get (0 );
144+ return new com .clickhouse .jdbc .types .Array (nestedColumn , JdbcUtils .arrayToObjectArray (value ));
137145 } else {
138- throw new SQLException ("Value of " + value .getClass () + " cannot be converted to " + type );
146+ Map <Class <?>, Function <Object , Object >> valueConverterMap = initValueConverterMapIfNeeded (value );
147+ return convertValue (value , type , valueConverterMap );
139148 }
140149 }
141- wasNull = value == null ;
142- return value == null ? defaultValue : value ;
143150 }
144151
145152 private void throwReadOnlyException () throws SQLException {
0 commit comments