Skip to content

bigquery: Table.Update cannot remove clustering from an existing table #14451

@sye-verily

Description

@sye-verily

Client

BigQuery (cloud.google.com/go/bigquery)

Environment

go version go1.26.0 darwin/arm64
cloud.google.com/go/bigquery v1.67.0 h1:GXleMyn/cu5+DPLy9Rz5f5IULWTLrepwbQnP/5qrVbY=
cloud.google.com/go/bigquery v1.67.0/go.mod h1:HQeP1AHFuAz0Y55heDSb0cjZIhnEkuwFRBGo6EEKHug=
google.golang.org/api v0.229.0 h1:p98ymMtqeJ5i3lIBMj5MpR9kzIIgzpHHh8vQ+vgAzx8=
google.golang.org/api v0.229.0/go.mod h1:wyDfmq5g1wYJWn29O22FDWN48P7Xcz0xz+LBpptYvB0=

Code and Dependencies

package main

import (
    "context"
    "fmt"

    "cloud.google.com/go/bigquery"
)

func main() {
    ctx := context.Background()
    client, _ := bigquery.NewClient(ctx, "my-project")
    bqTable := client.Dataset("my-dataset").Table("my-table")

    // Create a table with clustering.
    _ = bqTable.Create(ctx, &bigquery.TableMetadata{
        Schema:     bigquery.Schema{{Name: "id", Type: bigquery.StringFieldType}},
        Clustering: &bigquery.Clustering{Fields: []string{"id"}},
    })

    meta, _ := bqTable.Metadata(ctx)

    // Attempt to remove clustering by passing an empty Clustering.Fields.
    updated, _ := bqTable.Update(ctx, bigquery.TableMetadataToUpdate{
        Clustering: &bigquery.Clustering{Fields: []string{}},
    }, meta.ETag)

    fmt.Printf("Clustering after update: %+v\n", updated.Clustering)
    // Prints: Clustering after update: &{Fields:[id]}
    // Expected: Clustering after update: <nil>
}
go.mod
module example

go 1.26

require (
	cloud.google.com/go/bigquery v1.67.0
	google.golang.org/api v0.229.0
)

Expected behavior

When TableMetadataToUpdate.Clustering is set to &bigquery.Clustering{Fields: []string{}}, the clustering should be removed from the table. updated.Clustering should be nil after the call.

Actual behavior

The clustering update is silently ignored. The table retains its original clustering (Fields: ["id"]).

Additional context

The root cause is a chain of two issues:

  1. In table.go, when converting Clustering for the patch call, ForceSendFields is not set.

  2. In the underlying generated client, bigquery-gen.go, Clustering.Fields has omitempty, so an empty slice is dropped from the JSON payload entirely. The server receives no clustering change and preserves the existing configuration.

The fix in table.go would be to set ForceSendFields: []string{"Fields"} on the converted Clustering struct when Fields is empty, or to use NullFields to explicitly null out the clustering field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    api: bigqueryIssues related to the BigQuery API.triage meI really want to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions