Skip to content

Commit 0aad9ec

Browse files
fix(hashicorp/terraform-provider-google#23718): removing unnecessary … (#14659) (#10438)
[upstream:63cf48ea739c3db50912823c11a4ffdb13bb7002] Signed-off-by: Modular Magician <[email protected]>
1 parent 52cdfdb commit 0aad9ec

File tree

3 files changed

+157
-98
lines changed

3 files changed

+157
-98
lines changed

.changelog/14659.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
bigquery: fixed a crash in `google_bigquery_table` when configured as an external table with `parquet_options`
3+
```

google-beta/services/bigquery/resource_bigquery_table.go

Lines changed: 70 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,12 @@ func ResourceBigQueryTable() *schema.Resource {
13681368
Description: `Whether Terraform will prevent implicitly added columns in schema from showing diff.`,
13691369
},
13701370

1371+
"generated_schema_columns": {
1372+
Type: schema.TypeString,
1373+
Computed: true,
1374+
Description: `(Output-only) A list of autogenerated schema fields.`,
1375+
},
1376+
13711377
// TableConstraints: [Optional] Defines the primary key and foreign keys.
13721378
"table_constraints": {
13731379
Type: schema.TypeList,
@@ -1618,21 +1624,21 @@ func ResourceBigQueryTable() *schema.Resource {
16181624
}
16191625

16201626
// filterLiveSchemaByConfig compares a live schema from the BQ API with a schema from
1621-
// the Terraform config. It returns a new schema containing only the fields
1622-
// that are defined in the config, effectively removing any columns that were
1623-
// auto-generated by the service (e.g., hive partitioning keys).
1624-
//
1627+
// the Terraform config. It returns two values:
1628+
// 1. A new *bigquery.TableSchema containing a filtered list of fields that are defined in the config,
1629+
// effectively removing any columns that were auto-generated by the service (e.g., hive partitioning keys).
1630+
// 2. A slice of *bigquery.TableFieldSchema for the fields that were auto-generated by the service.
16251631
// Parameters:
16261632
// - liveSchema: The schema returned from a BigQuery API Read/Get call. This may contain extra columns.
16271633
// - configSchema: The schema built from the user's Terraform configuration (`d.Get("schema")`). This is the source of truth.
1628-
//
1629-
// Returns:
1630-
//
1631-
// A new *bigquery.TableSchema containing a filtered list of fields.
1632-
func filterLiveSchemaByConfig(liveSchema *bigquery.TableSchema, configSchema *bigquery.TableSchema) *bigquery.TableSchema {
1633-
if liveSchema == nil || configSchema == nil {
1634-
// If either schema is nil, there's nothing to compare, so return an empty schema.
1635-
return &bigquery.TableSchema{Fields: []*bigquery.TableFieldSchema{}}
1634+
func filterLiveSchemaByConfig(liveSchema *bigquery.TableSchema, configSchema *bigquery.TableSchema) (*bigquery.TableSchema, []*bigquery.TableFieldSchema) {
1635+
if liveSchema == nil {
1636+
// If live schema is nil, there's nothing to filter or collect.
1637+
return &bigquery.TableSchema{Fields: []*bigquery.TableFieldSchema{}}, nil
1638+
}
1639+
if configSchema == nil || len(configSchema.Fields) == 0 {
1640+
// If config schema is nil or empty, all live fields are considered auto-generated.
1641+
return &bigquery.TableSchema{Fields: []*bigquery.TableFieldSchema{}}, liveSchema.Fields
16361642
}
16371643

16381644
// 1. Create a lookup map of all column names defined in the configuration.
@@ -1645,19 +1651,21 @@ func filterLiveSchemaByConfig(liveSchema *bigquery.TableSchema, configSchema *bi
16451651
// 2. Iterate through the fields in the live schema and keep only the ones
16461652
// that exist in our configuration map.
16471653
var filteredFields []*bigquery.TableFieldSchema
1654+
var autogeneratedFields []*bigquery.TableFieldSchema
16481655
for _, liveField := range liveSchema.Fields {
16491656
// If the live field's name is present in the map of configured fields...
16501657
if _, ok := configFieldsMap[liveField.Name]; ok {
16511658
// ...then it's a field we care about. Add it to our filtered list.
16521659
filteredFields = append(filteredFields, liveField)
16531660
} else {
1654-
log.Printf("[DEBUG] auto-generated column `%s` dropped during Table read.", liveField.Name)
1661+
log.Printf("[DEBUG] auto-generated column `%s` collected during Table read.", liveField.Name)
1662+
autogeneratedFields = append(autogeneratedFields, liveField)
16551663
}
16561664
}
16571665

16581666
return &bigquery.TableSchema{
16591667
Fields: filteredFields,
1660-
}
1668+
}, autogeneratedFields
16611669
}
16621670

16631671
func resourceTable(d *schema.ResourceData, meta interface{}) (*bigquery.Table, error) {
@@ -2049,15 +2057,36 @@ func resourceBigQueryTableRead(d *schema.ResourceData, meta interface{}) error {
20492057
}
20502058

20512059
if res.Schema != nil {
2052-
table, err := resourceTable(d, meta)
2053-
if err != nil {
2054-
return err
2060+
var configSchema *bigquery.TableSchema
2061+
if v, ok := d.GetOk("schema"); ok {
2062+
_, viewPresent := d.GetOk("view")
2063+
_, materializedViewPresent := d.GetOk("materialized_view")
2064+
managePolicyTags := !viewPresent && !materializedViewPresent
2065+
configSchema, err = expandSchema(v, managePolicyTags)
2066+
if err != nil {
2067+
return err
2068+
}
20552069
}
20562070

20572071
schemaFiltered := res.Schema
20582072
ignore, ok := d.Get("ignore_auto_generated_schema").(bool)
20592073
if ok && ignore {
2060-
schemaFiltered = filterLiveSchemaByConfig(res.Schema, table.Schema)
2074+
var autogeneratedFields []*bigquery.TableFieldSchema
2075+
schemaFiltered, autogeneratedFields = filterLiveSchemaByConfig(res.Schema, configSchema)
2076+
if len(autogeneratedFields) > 0 {
2077+
autogeneratedFieldsJson, err := json.Marshal(autogeneratedFields)
2078+
if err != nil {
2079+
return fmt.Errorf("error marshalling autogenerated schema fields: %w", err)
2080+
}
2081+
if err := d.Set("generated_schema_columns", string(autogeneratedFieldsJson)); err != nil {
2082+
return fmt.Errorf("error setting generated_schema_columns: %w", err)
2083+
}
2084+
} else {
2085+
d.Set("generated_schema_columns", "")
2086+
}
2087+
} else {
2088+
// If not ignoring, ensure the field is cleared
2089+
d.Set("generated_schema_columns", "")
20612090
}
20622091
schema, err := flattenSchema(schemaFiltered)
20632092
if err != nil {
@@ -2144,6 +2173,25 @@ type TableReference struct {
21442173
tableID string
21452174
}
21462175

2176+
func addAutoGenSchemaFields(d *schema.ResourceData, table *bigquery.Table) error {
2177+
// When ignore_auto_generated_schema is true, we must include the autogenerated fields
2178+
// in the update payload to avoid the API thinking we're trying to delete them.
2179+
if ignore, enabled := d.Get("ignore_auto_generated_schema").(bool); enabled && ignore {
2180+
// Only proceed if the table has a schema to begin with.
2181+
if table.Schema != nil {
2182+
if autogenStr, ok := d.Get("generated_schema_columns").(string); ok && autogenStr != "" {
2183+
var autogenFields []*bigquery.TableFieldSchema
2184+
if err := json.Unmarshal([]byte(autogenStr), &autogenFields); err != nil {
2185+
return fmt.Errorf("failed to unmarshal autogenerated schema fields: %w", err)
2186+
}
2187+
table.Schema.Fields = append(table.Schema.Fields, autogenFields...)
2188+
log.Printf("[DEBUG] Appended %d autogenerated fields to schema for update", len(autogenFields))
2189+
}
2190+
}
2191+
}
2192+
return nil
2193+
}
2194+
21472195
func resourceBigQueryTableUpdate(d *schema.ResourceData, meta interface{}) error {
21482196
// If only client-side fields were modified, short-circuit the Update function to avoid sending an update API request.
21492197
clientSideFields := map[string]bool{"deletion_protection": true, "ignore_schema_changes": true, "ignore_auto_generated_schema": true, "table_metadata_view": true}
@@ -2169,6 +2217,10 @@ func resourceBigQueryTableUpdate(d *schema.ResourceData, meta interface{}) error
21692217
return err
21702218
}
21712219

2220+
if err := addAutoGenSchemaFields(d, table); err != nil {
2221+
return err
2222+
}
2223+
21722224
if table.ExternalDataConfiguration != nil && table.ExternalDataConfiguration.Schema != nil {
21732225
log.Printf("[INFO] Removing ExternalDataConfiguration.Schema when updating BigQuery table %s", d.Id())
21742226
table.ExternalDataConfiguration.Schema = nil

0 commit comments

Comments
 (0)