Struct parameters

Run a query with struct parameters.

Explore further

For detailed documentation that includes this code sample, see the following:

Code sample

Go

Before trying this sample, follow the Go setup instructions in the BigQuery quickstart using client libraries. For more information, see the BigQuery Go API reference documentation.

To authenticate to BigQuery, set up Application Default Credentials. For more information, see Set up authentication for client libraries.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/bigquery"
	"google.golang.org/api/iterator"
)

// queryWithStructParam demonstrates running a query and providing query parameters that include struct
// types.
func queryWithStructParam(w io.Writer, projectID string) error {
	// projectID := "my-project-id"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %w", err)
	}
	defer client.Close()

	type MyStruct struct {
		X int64
		Y string
	}
	q := client.Query(
		`SELECT @struct_value as s;`)
	q.Parameters = []bigquery.QueryParameter{
		{
			Name:  "struct_value",
			Value: MyStruct{X: 1, Y: "foo"},
		},
	}
	// Run the query and process the returned row iterator.
	it, err := q.Read(ctx)
	if err != nil {
		return fmt.Errorf("query.Read(): %w", err)
	}
	for {
		var row []bigquery.Value
		err := it.Next(&row)
		if err == iterator.Done {
			break
		}
		if err != nil {
			return err
		}
		fmt.Fprintln(w, row)
	}
	return nil
}

Java

Before trying this sample, follow the Java setup instructions in the BigQuery quickstart using client libraries. For more information, see the BigQuery Java API reference documentation.

To authenticate to BigQuery, set up Application Default Credentials. For more information, see Set up authentication for client libraries.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.QueryParameterValue;
import com.google.cloud.bigquery.TableResult;
import java.util.HashMap;
import java.util.Map;

public class QueryWithStructsParameters {

  public static void main(String[] args) {
    queryWithStructsParameters();
  }

  public static void queryWithStructsParameters() {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      // Create struct
      Map<String, QueryParameterValue> struct = new HashMap<>();
      struct.put("x", QueryParameterValue.int64(1));
      struct.put("y", QueryParameterValue.string("foo"));
      QueryParameterValue recordValue = QueryParameterValue.struct(struct);

      String query = "SELECT STRUCT(@recordField) AS s";
      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              .addNamedParameter("recordField", recordValue)
              .build();

      TableResult results = bigquery.query(queryConfig);

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s", val.toString())));

      System.out.println("Query with struct parameter performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Rust

use google_cloud_bigquery::FromRow;
use google_cloud_bigquery::client::BigQuery;
use google_cloud_bigquery::model::{
    QueryParameter, QueryParameterStructType, QueryParameterType, QueryParameterValue,
};

#[derive(FromRow, Debug)]
struct NameCount {
    name: String,
    number: i64,
}

pub async fn sample(project_id: &str) -> anyhow::Result<()> {
    let client = BigQuery::builder().build().await?;

    let mut rows = client
        .query(
            "SELECT name, number \
        FROM `bigquery-public-data.usa_names.usa_1910_2013` \
        WHERE state = @record.state AND gender = @record.gender \
        LIMIT 10",
        )
        .with_project_id(project_id)
        .set_parameter_mode("NAMED")
        .set_query_parameters([QueryParameter::new()
            .set_name("record")
            .set_parameter_type(
                QueryParameterType::new()
                    .set_type("STRUCT")
                    .set_struct_types([
                        QueryParameterStructType::new()
                            .set_name("state")
                            .set_type(QueryParameterType::new().set_type("STRING")),
                        QueryParameterStructType::new()
                            .set_name("gender")
                            .set_type(QueryParameterType::new().set_type("STRING")),
                    ]),
            )
            .set_parameter_value(QueryParameterValue::new().set_struct_values([
                ("state", QueryParameterValue::new().set_value("TX")),
                ("gender", QueryParameterValue::new().set_value("F")),
            ]))])
        .set_location("US")
        .run()
        .await?
        .until_done()
        .await?
        .read();

    while let Some(row) = rows.next().await.transpose()? {
        let name_count: NameCount = row.try_into()?;
        println!("Name: {}, Number: {}", name_count.name, name_count.number);
    }
    Ok(())
}

What's next

To search and filter code samples for other Google Cloud products, see the Google Cloud sample browser.