Description
When querying a table that has TIMESTAMP fields inside a nested RECORD (struct), the emulator returns the timestamp value as an RFC3339 string (e.g., "2026-05-20T11:00:00Z") instead of the integer microseconds-since-epoch format that real BigQuery uses (e.g., "1716202200000000").
Top-level TIMESTAMP fields are returned correctly as epoch microseconds.
This causes the Go BigQuery client (cloud.google.com/go/bigquery) to fail with:
strconv.ParseInt: parsing "2026-05-20T11:00:00Z": invalid syntax
...because convertBasicType for TimestampFieldType expects a numeric string.
Reproduction
package main
import (
"context"
"fmt"
"time"
"cloud.google.com/go/bigquery"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
)
type bqRow map[string]bigquery.Value
func (r bqRow) Save() (map[string]bigquery.Value, string, error) {
return map[string]bigquery.Value(r), bigquery.NoDedupeID, nil
}
func main() {
ctx := context.Background()
client, _ := bigquery.NewClient(ctx, "local",
option.WithEndpoint("http://localhost:9050"),
option.WithoutAuthentication(),
)
defer client.Close()
_ = client.Dataset("ts_test").Create(ctx, &bigquery.DatasetMetadata{})
_ = client.Dataset("ts_test").Table("nested_ts").Delete(ctx)
schema := bigquery.Schema{
{Name: "id", Type: bigquery.StringFieldType},
{Name: "top_ts", Type: bigquery.TimestampFieldType},
{Name: "nested", Type: bigquery.RecordFieldType, Repeated: true, Schema: bigquery.Schema{
{Name: "name", Type: bigquery.StringFieldType},
{Name: "nested_ts", Type: bigquery.TimestampFieldType},
}},
}
_ = client.Dataset("ts_test").Table("nested_ts").Create(ctx, &bigquery.TableMetadata{Schema: schema})
r := bqRow{
"id": "test-1",
"top_ts": time.Date(2026, 5, 20, 10, 30, 0, 0, time.UTC),
"nested": []map[string]bigquery.Value{
{"name": "activity-1", "nested_ts": time.Date(2026, 5, 20, 11, 0, 0, 0, time.UTC)},
},
}
_ = client.Dataset("ts_test").Table("nested_ts").Inserter().Put(ctx, r)
q := client.Query("SELECT * FROM `local.ts_test.nested_ts`")
it, _ := q.Read(ctx)
var values []bigquery.Value
err := it.Next(&values)
fmt.Printf("error: %v\n", err) // strconv.ParseInt: parsing "2026-05-20T11:00:00Z": invalid syntax
}
Expected behavior
Nested TIMESTAMP fields should be returned in the same format as top-level TIMESTAMP fields — integer microseconds since Unix epoch encoded as a string (e.g., "1716202200000000").
Environment
- Emulator image:
ghcr.io/goccy/bigquery-emulator:latest
- Go BigQuery client:
cloud.google.com/go/bigquery v1.77.0
- Started with:
bigquery-emulator --project=local --port=9050
Description
When querying a table that has
TIMESTAMPfields inside a nestedRECORD(struct), the emulator returns the timestamp value as an RFC3339 string (e.g.,"2026-05-20T11:00:00Z") instead of the integer microseconds-since-epoch format that real BigQuery uses (e.g.,"1716202200000000").Top-level
TIMESTAMPfields are returned correctly as epoch microseconds.This causes the Go BigQuery client (
cloud.google.com/go/bigquery) to fail with:...because
convertBasicTypeforTimestampFieldTypeexpects a numeric string.Reproduction
Expected behavior
Nested TIMESTAMP fields should be returned in the same format as top-level TIMESTAMP fields — integer microseconds since Unix epoch encoded as a string (e.g.,
"1716202200000000").Environment
ghcr.io/goccy/bigquery-emulator:latestcloud.google.com/go/bigquery v1.77.0bigquery-emulator --project=local --port=9050