Skip to content

Commit

Permalink
add foreign type info and definition to google_bigquery_table beta
Browse files Browse the repository at this point in the history
  • Loading branch information
wj-chen committed Jan 8, 2025
1 parent cb117a3 commit 85188e8
Show file tree
Hide file tree
Showing 5 changed files with 188 additions and 2 deletions.
22 changes: 22 additions & 0 deletions mmv1/products/bigquery/Table.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,28 @@ properties:
- 'TIME'
- 'DATETIME'
- 'RECORD'
- 'FOREIGN'
- name: 'foreignTypeDefinition'
type: String
description: |
Definition of the foreign data type.
Only valid for top-level schema fields (not nested fields).
If the type is FOREIGN, this field is required.
min_version: beta
- name: 'schemaForeignTypeInfo'
type: NestedObject
description: |
Specifies metadata of the foreign data type definition in field schema.
min_version: beta
properties:
- name: 'typeSystem'
type: Enum
description: |
The foreign type of the table.
required: true
enum_values:
- 'HIVE'
min_version: beta
- name: 'encryptionConfiguration'
type: NestedObject
description: Custom encryption configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ func jsonCompareWithMapKeyOverride(key string, a, b interface{}, compareMapKeyVa
unionOfKeys[subKey] = true
}

{{- if ne $.TargetVersionName "ga" }}
// Disregard "type" and "fields" if "foreignTypeDefinition" is present since they may have been modified by the server.
if _, ok := unionOfKeys["foreignTypeDefinition"]; ok {
delete(unionOfKeys, "type")
delete(unionOfKeys, "fields")
}

{{- end }}
for subKey := range unionOfKeys {
eq := compareMapKeyVal(subKey, objectA, objectB)
if !eq {
Expand Down Expand Up @@ -323,6 +331,15 @@ func resourceBigQueryTableSchemaIsChangeable(old, new interface{}, isExternalTab
for key := range objectNew {
unionOfKeys[key] = true
}

{{- if ne $.TargetVersionName "ga" }}
// Disregard "type" and "fields" if "foreignTypeDefinition" is present since they may have been modified by the server.
if _, ok := unionOfKeys["foreignTypeDefinition"]; ok {
delete(unionOfKeys, "type")
delete(unionOfKeys, "fields")
}

{{- end }}
for key := range unionOfKeys {
valOld := objectOld[key]
valNew := objectNew[key]
Expand Down Expand Up @@ -992,6 +1009,25 @@ func ResourceBigQueryTable() *schema.Resource {
DiffSuppressFunc: bigQueryTableSchemaDiffSuppress,
Description: `A JSON schema for the table.`,
},
{{- if ne $.TargetVersionName "ga" }}
// SchemaForeignTypeInfo: [Optional] Specifies metadata of the foreign data type definition in field schema.
"schema_foreign_type_info": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Description: "Specifies metadata of the foreign data type definition in field schema.",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
// TypeSystem: [Required] Specifies the system which defines the foreign data type.
"type_system": {
Type: schema.TypeString,
Required: true,
Description: `Specifies the system which defines the foreign data type.`,
},
},
},
},
{{- end }}
// View: [Optional] If specified, configures this table as a view.
"view": {
Type: schema.TypeList,
Expand Down Expand Up @@ -1627,6 +1663,14 @@ func resourceTable(d *schema.ResourceData, meta interface{}) (*bigquery.Table, e
table.Schema = schema
}

{{- if ne $.TargetVersionName "ga" }}
if v, ok := d.GetOk("schema_foreign_type_info"); ok {
if table.Schema != nil {
table.Schema.ForeignTypeInfo = expandForeignTypeInfo(v)
}
}

{{- end }}
if v, ok := d.GetOk("time_partitioning"); ok {
table.TimePartitioning = expandTimePartitioning(v)
}
Expand Down Expand Up @@ -1930,6 +1974,14 @@ func resourceBigQueryTableRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("schema", schema); err != nil {
return fmt.Errorf("Error setting schema: %s", err)
}
{{- if ne $.TargetVersionName "ga" }}
if res.Schema.ForeignTypeInfo != nil {
foreignTypeInfo := flattenForeignTypeInfo(res.Schema.ForeignTypeInfo)
if err := d.Set("schema_foreign_type_info", foreignTypeInfo); err != nil {
return fmt.Errorf("Error setting schema_foreign_type_info: %s", err)
}
}
{{- end }}
}

if res.View != nil {
Expand Down Expand Up @@ -2729,6 +2781,32 @@ func schemaHasRequiredFields(schema *bigquery.TableSchema) bool {
return false
}

{{- if ne $.TargetVersionName "ga" }}
func expandForeignTypeInfo(configured interface{}) *bigquery.ForeignTypeInfo {
if len(configured.([]interface{})) == 0 {
return nil
}

raw := configured.([]interface{})[0].(map[string]interface{})
fti := &bigquery.ForeignTypeInfo{}

if v, ok := raw["type_system"]; ok {
fti.TypeSystem = v.(string)
}

return fti
}

func flattenForeignTypeInfo(fti *bigquery.ForeignTypeInfo) []map[string]interface{} {
if fti == nil {
return nil
}

result := map[string]interface{}{"type_system": fti.TypeSystem}
return []map[string]interface{}{result}
}

{{- end }}
func expandTimePartitioning(configured interface{}) *bigquery.TimePartitioning {
raw := configured.([]interface{})[0].(map[string]interface{})
tp := &bigquery.TimePartitioning{Type: raw["type"].(string)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,13 @@ func TestBigQueryTableSchemaDiffSuppress(t *testing.T) {
]`,
ExpectDiffSuppress: true,
},
{{- if ne $.TargetVersionName "ga" }}
"foreignTypeDefinition from generated schema -> original schema": {
Old: "[{\"name\": \"someValue\", \"type\": \"RECORD\", \"foreignTypeDefinition\" : \"STRUCT<id:STRING, name:STRING>\", \"fields\": [{\"name\": \"id\", \"type\": \"STRING\"}, {\"name\": \"name\", \"type\": \"STRING\"}]}]",
New: "[{\"name\": \"someValue\", \"type\": \"FOREIGN\", \"foreignTypeDefinition\" : \"STRUCT<id:STRING, name:STRING>\"}]",
ExpectDiffSuppress: true,
},
{{- end }}
}

for tn, tc := range cases {
Expand All @@ -376,10 +383,10 @@ func TestBigQueryTableSchemaDiffSuppress(t *testing.T) {

var a, b interface{}
if err := json.Unmarshal([]byte(tc.Old), &a); err != nil {
t.Fatalf(fmt.Sprintf("unable to unmarshal old json - %v", err))
t.Fatalf("%v", fmt.Sprintf("unable to unmarshal old json - %v", err))
}
if err := json.Unmarshal([]byte(tc.New), &b); err != nil {
t.Fatalf(fmt.Sprintf("unable to unmarshal new json - %v", err))
t.Fatalf("%v", fmt.Sprintf("unable to unmarshal new json - %v", err))
}
if bigQueryTableSchemaDiffSuppress("schema", tc.Old, tc.New, nil) != tc.ExpectDiffSuppress {
t.Fatalf("bad: %s, %q => %q expect DiffSuppress to return %t", tn, tc.Old, tc.New, tc.ExpectDiffSuppress)
Expand Down Expand Up @@ -577,6 +584,14 @@ var testUnitBigQueryDataTableIsChangeableTestCases = []testUnitBigQueryDataTable
]`,
changeable: true,
},
{{- if ne $.TargetVersionName "ga" }}
{
name: "foreignTypeDefinition",
jsonOld: "[{\"name\": \"someValue\", \"type\" : \"FOREIGN\", \"foreignTypeDefinition\" : \"INTEGER\" }]",
jsonNew: "[{\"name\": \"someValue\", \"type\" : \"FOREIGN\", \"foreignTypeDefinition\" : \"STRING\" }]",
changeable: true,
},
{{- end }}
}

func TestUnitBigQueryDataTable_schemaIsChangeable(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,33 @@ func TestAccBigQueryTable_externalCatalogTableOptions(t *testing.T) {
})
}

func TestAccBigQueryTable_foreignTypeInfo(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"project_id": envvar.GetTestProjectFromEnv(),
"dataset_id": fmt.Sprintf("tf_test_dataset_%s", acctest.RandString(t, 10)),
"table_id": fmt.Sprintf("tf_test_table_%s", acctest.RandString(t, 10)),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
CheckDestroy: testAccCheckBigQueryTableDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccBigQueryTable_foreignTypeInfo_basic(context),
},
{
ResourceName: "google_bigquery_table.test",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"deletion_protection"},
},
},
})
}

{{- end }}
func testAccCheckBigQueryExtData(t *testing.T, expectedQuoteChar string) resource.TestCheckFunc {
return func(s *terraform.State) error {
Expand Down Expand Up @@ -4662,6 +4689,39 @@ EOF
`, context)
}

func testAccBigQueryTable_foreignTypeInfo_basic(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_bigquery_dataset" "test" {
provider = google-beta

dataset_id = "%{dataset_id}"
location = "EU"
}

resource "google_bigquery_table" "test" {
provider = google-beta

deletion_protection = false
dataset_id = "${google_bigquery_dataset.test.dataset_id}"
table_id = "%{table_id}"

schema = <<EOF
[
{
"name": "struct_",
"type": "FOREIGN",
"foreignTypeDefinition": "STRUCT<id:STRING, name:STRING>"
}
]
EOF

schema_foreign_type_info {
type_system = "HIVE"
}
}
`, context)
}

{{- end }}
var TEST_CSV = `lifelock,LifeLock,,web,Tempe,AZ,1-May-07,6850000,USD,b
lifelock,LifeLock,,web,Tempe,AZ,1-Oct-06,6000000,USD,a
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ The following arguments are supported:
with `external_data_configuration.schema`. Otherwise, schemas must be
specified with this top-level field.

* `schema_foreign_type_info` - (Optional, [Beta]
(https://terraform.io/docs/providers/google/guides/provider_versions.html))
Specifies metadata of the foreign data type definition in field schema.
Structure is [documented below](#nested_schema_foreign_type_info).

* `time_partitioning` - (Optional) If specified, configures time-based
partitioning for this table. Structure is [documented below](#nested_time_partitioning).

Expand Down Expand Up @@ -374,6 +379,12 @@ The following arguments are supported:

* `enable_list_inference` - (Optional) Indicates whether to use schema inference specifically for Parquet LIST logical type.

<a name="nested_schema_foreign_type_info"></a>The `schema_foreign_type_info` block supports:

* `type_system` - (Required, [Beta]
(https://terraform.io/docs/providers/google/guides/provider_versions.html))
Specifies the system which defines the foreign data type.

<a name="nested_time_partitioning"></a>The `time_partitioning` block supports:

* `expiration_ms` - (Optional) Number of milliseconds for which to keep the
Expand Down

0 comments on commit 85188e8

Please sign in to comment.