2626import com .google .cloud .Timestamp ;
2727import com .google .common .base .Function ;
2828import com .google .common .collect .ImmutableList ;
29+ import com .google .common .collect .ImmutableMap ;
2930import com .google .common .collect .Lists ;
3031import com .google .common .io .BaseEncoding ;
3132import java .io .Serializable ;
3233import java .math .BigDecimal ;
3334import java .util .ArrayList ;
3435import java .util .Date ;
36+ import java .util .HashMap ;
3537import java .util .List ;
38+ import java .util .Map ;
3639import javax .annotation .Nullable ;
3740import org .threeten .bp .Instant ;
3841import org .threeten .bp .ZoneOffset ;
@@ -127,12 +130,27 @@ public Builder setArrayValues(List<QueryParameterValue> arrayValues) {
127130
128131 abstract Builder setArrayValuesInner (ImmutableList <QueryParameterValue > arrayValues );
129132
133+ /** Sets struct values. The type must set to STRUCT. */
134+ public Builder setStructValues (Map <String , QueryParameterValue > structValues ) {
135+ setStructTypes (ImmutableMap .copyOf (structValues ));
136+ return setStructValuesInner (ImmutableMap .copyOf (structValues ));
137+ }
138+
139+ abstract Builder setStructValuesInner (Map <String , QueryParameterValue > structValues );
140+
130141 /** Sets the parameter data type. */
131142 public abstract Builder setType (StandardSQLTypeName type );
132143
133144 /** Sets the data type of the array elements. The type must set to ARRAY. */
134145 public abstract Builder setArrayType (StandardSQLTypeName arrayType );
135146
147+ /** Sets the data type of the struct elements. The type must set to STRUCT. */
148+ public Builder setStructTypes (Map <String , QueryParameterValue > structTypes ) {
149+ return setStructTypesInner (structTypes );
150+ }
151+
152+ abstract Builder setStructTypesInner (Map <String , QueryParameterValue > structTypes );
153+
136154 /** Creates a {@code QueryParameterValue} object. */
137155 public abstract QueryParameterValue build ();
138156 }
@@ -154,13 +172,31 @@ public List<QueryParameterValue> getArrayValues() {
154172 @ Nullable
155173 abstract ImmutableList <QueryParameterValue > getArrayValuesInner ();
156174
175+ /** Returns the struct values of this parameter. The returned map, if not null, is immutable. */
176+ @ Nullable
177+ public Map <String , QueryParameterValue > getStructValues () {
178+ return getStructValuesInner ();
179+ }
180+
181+ @ Nullable
182+ abstract Map <String , QueryParameterValue > getStructValuesInner ();
183+
157184 /** Returns the data type of this parameter. */
158185 public abstract StandardSQLTypeName getType ();
159186
160187 /** Returns the data type of the array elements. */
161188 @ Nullable
162189 public abstract StandardSQLTypeName getArrayType ();
163190
191+ /** Returns the data type of the struct elements. */
192+ @ Nullable
193+ public Map <String , QueryParameterValue > getStructTypes () {
194+ return getStructTypesInner ();
195+ }
196+
197+ @ Nullable
198+ abstract Map <String , QueryParameterValue > getStructTypesInner ();
199+
164200 /** Creates a {@code QueryParameterValue} object with the given value and type. */
165201 public static <T > QueryParameterValue of (T value , Class <T > type ) {
166202 return of (value , classToType (type ));
@@ -274,6 +310,17 @@ public static <T> QueryParameterValue array(T[] array, StandardSQLTypeName type)
274310 .build ();
275311 }
276312
313+ /**
314+ * Creates a map with {@code QueryParameterValue} object and a type of STRUCT the given struct
315+ * element type.
316+ */
317+ public static QueryParameterValue struct (Map <String , QueryParameterValue > struct ) {
318+ return QueryParameterValue .newBuilder ()
319+ .setStructValues (struct )
320+ .setType (StandardSQLTypeName .STRUCT )
321+ .build ();
322+ }
323+
277324 private static <T > StandardSQLTypeName classToType (Class <T > type ) {
278325 if (Boolean .class .isAssignableFrom (type )) {
279326 return StandardSQLTypeName .BOOL ;
@@ -398,6 +445,14 @@ com.google.api.services.bigquery.model.QueryParameterValue toValuePb() {
398445 valuePb .setArrayValues (
399446 Lists .transform (getArrayValues (), QueryParameterValue .TO_VALUE_PB_FUNCTION ));
400447 }
448+ if (getStructValues () != null ) {
449+ Map <String , com .google .api .services .bigquery .model .QueryParameterValue > structValues =
450+ new HashMap <>();
451+ for (Map .Entry <String , QueryParameterValue > structValue : getStructValues ().entrySet ()) {
452+ structValues .put (structValue .getKey (), structValue .getValue ().toValuePb ());
453+ }
454+ valuePb .setStructValues (structValues );
455+ }
401456 return valuePb ;
402457 }
403458
@@ -409,14 +464,24 @@ QueryParameterType toTypePb() {
409464 arrayTypePb .setType (getArrayType ().toString ());
410465 typePb .setArrayType (arrayTypePb );
411466 }
467+ if (getStructTypes () != null ) {
468+ List <QueryParameterType .StructTypes > structTypes = new ArrayList <>();
469+ for (Map .Entry <String , QueryParameterValue > entry : getStructTypes ().entrySet ()) {
470+ QueryParameterType .StructTypes structType = new QueryParameterType .StructTypes ();
471+ structType .setName (entry .getKey ());
472+ structType .setType (entry .getValue ().toTypePb ());
473+ structTypes .add (structType );
474+ }
475+ typePb .setStructTypes (structTypes );
476+ }
412477 return typePb ;
413478 }
414479
415480 static QueryParameterValue fromPb (
416481 com .google .api .services .bigquery .model .QueryParameterValue valuePb ,
417482 QueryParameterType typePb ) {
418483 Builder valueBuilder = newBuilder ();
419-
484+ Map < String , QueryParameterType > parameterTypes = new HashMap <>();
420485 StandardSQLTypeName type = StandardSQLTypeName .valueOf (typePb .getType ());
421486 valueBuilder .setType (type );
422487 if (type == StandardSQLTypeName .ARRAY ) {
@@ -431,10 +496,35 @@ static QueryParameterValue fromPb(
431496 }
432497 valueBuilder .setArrayValues (arrayValues .build ());
433498 }
499+ } else if (type == StandardSQLTypeName .STRUCT ) {
500+ Map <String , QueryParameterValue > structTypes = new HashMap <>();
501+ for (QueryParameterType .StructTypes types : typePb .getStructTypes ()) {
502+ structTypes .put (
503+ types .getName (),
504+ QueryParameterValue .newBuilder ()
505+ .setType (StandardSQLTypeName .valueOf (types .getType ().getType ()))
506+ .build ());
507+ }
508+ valueBuilder .setStructTypes (structTypes );
509+ if (valuePb == null || valuePb .getStructValues () == null ) {
510+ valueBuilder .setStructValues (ImmutableMap .<String , QueryParameterValue >of ());
511+ } else {
512+ Map <String , QueryParameterValue > structValues = new HashMap <>();
513+ for (QueryParameterType .StructTypes structType : typePb .getStructTypes ()) {
514+ parameterTypes .put (structType .getName (), structType .getType ());
515+ }
516+ for (Map .Entry <String , com .google .api .services .bigquery .model .QueryParameterValue >
517+ structValue : valuePb .getStructValues ().entrySet ()) {
518+ structValues .put (
519+ structValue .getKey (),
520+ QueryParameterValue .fromPb (
521+ structValue .getValue (), parameterTypes .get (structValue .getKey ())));
522+ }
523+ valueBuilder .setStructValues (structValues );
524+ }
434525 } else {
435526 valueBuilder .setValue (valuePb == null ? "" : valuePb .getValue ());
436527 }
437-
438528 return valueBuilder .build ();
439529 }
440530}
0 commit comments