22
33import java .sql .SQLException ;
44import java .util .ArrayList ;
5+ import java .util .Arrays ;
56import java .util .List ;
67
78import tech .ydb .jdbc .YdbConst ;
1011import tech .ydb .table .query .Params ;
1112import tech .ydb .table .values .ListType ;
1213import tech .ydb .table .values .OptionalType ;
14+ import tech .ydb .table .values .TupleType ;
1315import tech .ydb .table .values .Type ;
1416import tech .ydb .table .values .Value ;
1517import tech .ydb .table .values .VoidValue ;
2022 */
2123public class InListJdbcPrm {
2224 private static final Value <?> NULL = VoidValue .of ();
23- private final YdbTypes types ;
25+ private final YdbTypes ydbTypes ;
2426 private final String listName ;
2527 private final List <Item > items = new ArrayList <>();
26- private TypeDescription type ;
28+ private final Item [][] tuples ;
29+ private final TypeDescription [] tupleTypes ;
2730
28- public InListJdbcPrm (YdbTypes types , String listName , int listSize ) {
29- this .types = types ;
31+ public InListJdbcPrm (YdbTypes types , String listName , int listSize , int tupleSize ) {
32+ this .ydbTypes = types ;
3033 this .listName = listName ;
31- for (int idx = 0 ; idx < listSize ; idx ++) {
32- items .add (new Item (listName , idx ));
34+ this .tupleTypes = new TypeDescription [tupleSize ];
35+ this .tuples = new Item [listSize ][];
36+ for (int idx = 0 ; idx < listSize ; idx += 1 ) {
37+ Item [] tuple = new Item [tupleSize ];
38+ for (int memberIdx = 0 ; memberIdx < tupleSize ; memberIdx += 1 ) {
39+ tuple [memberIdx ] = new Item (listName , idx * tupleSize + memberIdx , memberIdx );
40+ items .add (tuple [memberIdx ]);
41+ }
42+ tuples [idx ] = tuple ;
3343 }
3444 }
3545
@@ -38,47 +48,90 @@ public List<? extends JdbcPrm> toJdbcPrmList() {
3848 }
3949
4050 private Value <?> buildList () throws SQLException {
41- if (type == null ) {
42- throw new SQLException (YdbConst .PARAMETER_TYPE_UNKNOWN );
51+ TypeBuilder [] types = new TypeBuilder [tupleTypes .length ];
52+ for (int idx = 0 ; idx < tupleTypes .length ; idx += 1 ) {
53+ if (tupleTypes [idx ] == null ) {
54+ throw new SQLException (YdbConst .MISSING_VALUE_FOR_PARAMETER + tuples [0 ][idx ].name );
55+ }
56+ types [idx ] = new TypeBuilder (tupleTypes [idx ].ydbType ());
4357 }
4458
45- boolean hasNull = false ;
4659 for (Item item : items ) {
4760 if (item .value == null ) {
4861 throw new SQLException (YdbConst .MISSING_VALUE_FOR_PARAMETER + item .name );
4962 }
50- hasNull = hasNull || item .value == NULL ;
63+ types [ item .memberId ]. validateOptional ( item . value ) ;
5164 }
5265
53- List <Value <?>> values = new ArrayList <>();
54- if (!hasNull ) {
66+ if (types .length == 1 ) { // Simple list
67+ TypeBuilder type = types [0 ];
68+ List <Value <?>> values = new ArrayList <>();
5569 for (Item item : items ) {
56- values .add (item .value );
70+ values .add (type . makeValue ( item .value ) );
5771 }
58- return ListType .of (type .ydbType ()).newValue (values );
72+ return ListType .of (type .makeType ()).newValue (values );
5973 }
6074
61- OptionalType optional = type .ydbType ().makeOptional ();
62- for (Item item : items ) {
63- if (item .value == NULL ) {
64- values .add (optional .emptyValue ());
65- } else {
66- values .add (item .value .makeOptional ());
75+ Type [] tupleMemberTypes = new Type [tupleTypes .length ];
76+ for (int idx = 0 ; idx < tupleTypes .length ; idx += 1 ) {
77+ tupleMemberTypes [idx ] = types [idx ].makeType ();
78+ }
79+
80+ TupleType tupleType = TupleType .ofOwn (tupleMemberTypes );
81+ List <Value <?>> values = new ArrayList <>();
82+ for (Item [] tupleItems : tuples ) {
83+ Value <?>[] tupleValues = new Value <?>[tupleItems .length ];
84+ for (int idx = 0 ; idx < tupleItems .length ; idx += 1 ) {
85+ tupleValues [idx ] = types [idx ].makeValue (tupleItems [idx ].value );
6786 }
87+ values .add (tupleType .newValueOwn (tupleValues ));
6888 }
6989
70- return ListType .of (optional ).newValue (values );
90+ return ListType .of (tupleType ).newValue (values );
91+ }
92+
93+ private class TypeBuilder {
94+ private final Type type ;
95+ private final OptionalType optional ;
7196
97+ private boolean isOptional = false ;
98+
99+ TypeBuilder (Type type ) {
100+ this .type = type ;
101+ this .optional = type .makeOptional ();
102+ }
103+
104+ void validateOptional (Value <?> value ) {
105+ this .isOptional = isOptional || value == NULL ;
106+ }
107+
108+ Value <?> makeValue (Value <?> value ) {
109+ if (!isOptional ) {
110+ return value ;
111+ }
112+
113+ if (value == NULL ) {
114+ return optional .emptyValue ();
115+ }
116+
117+ return value .makeOptional ();
118+ }
119+
120+ Type makeType () {
121+ return isOptional ? optional : type ;
122+ }
72123 }
73124
74125 private class Item implements JdbcPrm {
75126 private final String name ;
76127 private final int index ;
128+ private final int memberId ;
77129 private Value <?> value = null ;
78130
79- Item (String listName , int index ) {
131+ Item (String listName , int index , int tupleIdx ) {
80132 this .name = listName + "[" + index + "]" ;
81133 this .index = index ;
134+ this .memberId = tupleIdx ;
82135 }
83136
84137 @ Override
@@ -88,13 +141,13 @@ public String getName() {
88141
89142 @ Override
90143 public TypeDescription getType () {
91- return type ;
144+ return tupleTypes [ memberId ] ;
92145 }
93146
94147 @ Override
95148 public void setValue (Object obj , int sqlType ) throws SQLException {
96- if (type == null ) {
97- Type ydbType = types .findType (obj , sqlType );
149+ if (tupleTypes [ memberId ] == null ) {
150+ Type ydbType = ydbTypes .findType (obj , sqlType );
98151 if (ydbType == null ) {
99152 if (obj == null ) {
100153 value = NULL ;
@@ -104,15 +157,15 @@ public void setValue(Object obj, int sqlType) throws SQLException {
104157 }
105158 }
106159
107- type = types .find (ydbType );
160+ tupleTypes [ memberId ] = ydbTypes .find (ydbType );
108161 }
109162
110163 if (obj == null ) {
111164 value = NULL ;
112165 return ;
113166 }
114167
115- value = type .toYdbValue (obj );
168+ value = tupleTypes [ memberId ] .toYdbValue (obj );
116169 }
117170
118171 @ Override
@@ -126,7 +179,7 @@ public void copyToParams(Params params) throws SQLException {
126179 public void reset () {
127180 value = null ;
128181 if (index == items .size () - 1 ) { // last prm reset type
129- type = null ;
182+ Arrays . fill ( tupleTypes , null ) ;
130183 }
131184 }
132185 }
0 commit comments