diff --git a/.changelog/11101.txt b/.changelog/11101.txt new file mode 100644 index 0000000000..33b6ad1f91 --- /dev/null +++ b/.changelog/11101.txt @@ -0,0 +1,3 @@ +```release-note:breaking-change +bigquery: added validation to prevent table view creation if schema contains required fields for `google_bigquery_table` resource +``` \ No newline at end of file diff --git a/google-beta/services/bigquery/resource_bigquery_table.go b/google-beta/services/bigquery/resource_bigquery_table.go index c6ee3b9701..8bcf74a0d7 100644 --- a/google-beta/services/bigquery/resource_bigquery_table.go +++ b/google-beta/services/bigquery/resource_bigquery_table.go @@ -1593,6 +1593,9 @@ func resourceBigQueryTableCreate(d *schema.ResourceData, meta interface{}) error } if table.View != nil && table.Schema != nil { + if schemaHasRequiredFields(table.Schema) { + return errors.New("Schema cannot contain required fields when creating a view") + } log.Printf("[INFO] Removing schema from table definition because BigQuery does not support setting schema on view creation") schemaBack := table.Schema @@ -2551,6 +2554,15 @@ func setEmptyPolicyTagsInSchema(field *bigquery.TableFieldSchema) { } } +func schemaHasRequiredFields(schema *bigquery.TableSchema) bool { + for _, field := range schema.Fields { + if "REQUIRED" == field.Mode { + return true + } + } + return false +} + func expandTimePartitioning(configured interface{}) *bigquery.TimePartitioning { raw := configured.([]interface{})[0].(map[string]interface{}) tp := &bigquery.TimePartitioning{Type: raw["type"].(string)} diff --git a/google-beta/services/bigquery/resource_bigquery_table_test.go b/google-beta/services/bigquery/resource_bigquery_table_test.go index aece952eae..e84fbc2d95 100644 --- a/google-beta/services/bigquery/resource_bigquery_table_test.go +++ b/google-beta/services/bigquery/resource_bigquery_table_test.go @@ -1497,6 +1497,23 @@ func TestAccBigQueryTable_invalidSchemas(t *testing.T) { }) } +func TestAccBigQueryTable_schemaWithRequiredFieldAndView(t *testing.T) { + datasetID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + tableID := fmt.Sprintf("tf_test_%s", acctest.RandString(t, 10)) + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccBigQueryTableWithSchemaWithRequiredFieldAndView(datasetID, tableID), + ExpectError: regexp.MustCompile("Schema cannot contain required fields when creating a view"), + }, + }, + }) +} + func TestAccBigQueryTable_TableReplicationInfo_ConflictsWithView(t *testing.T) { t.Parallel() @@ -3982,6 +3999,42 @@ resource "google_bigquery_table" "test" { `, datasetID, tableID) } +func testAccBigQueryTableWithSchemaWithRequiredFieldAndView(datasetID, tableID string) string { + return fmt.Sprintf(` +resource "google_bigquery_dataset" "test" { + dataset_id = "%s" +} + +resource "google_bigquery_table" "test" { + deletion_protection = false + table_id = "%s" + dataset_id = google_bigquery_dataset.test.dataset_id + schema = <