Skip to content

Commit

Permalink
feat(bigquery): add support for parameterized types (#4103)
Browse files Browse the repository at this point in the history
* feat(bigquery): add support for parameterized types

Exposes type parameterization constraints for
STRING, BYTES, NUMERIC, BIGNUMERIC types.

* Update bigquery/schema.go

Co-authored-by: Cody Oss <6331106+codyoss@users.noreply.github.com>

Co-authored-by: Cody Oss <6331106+codyoss@users.noreply.github.com>
  • Loading branch information
shollyman and codyoss committed May 14, 2021
1 parent a2d137d commit a2330e4
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
30 changes: 30 additions & 0 deletions bigquery/integration_test.go
Expand Up @@ -249,6 +249,36 @@ func TestIntegration_TableCreate(t *testing.T) {
}
}

func TestIntegration_TableCreateWithConstraints(t *testing.T) {
if client == nil {
t.Skip("Integration tests skipped")
}
table := dataset.Table("constraints")
schema := Schema{
{Name: "str_col", Type: StringFieldType, MaxLength: 10},
{Name: "bytes_col", Type: BytesFieldType, MaxLength: 150},
{Name: "num_col", Type: NumericFieldType, Precision: 20},
{Name: "bignumeric_col", Type: BigNumericFieldType, Precision: 30, Scale: 5},
}
err := table.Create(context.Background(), &TableMetadata{
Schema: schema,
ExpirationTime: testTableExpiration.Add(5 * time.Minute),
})
if err != nil {
t.Fatalf("table create error: %v", err)
}

meta, err := table.Metadata(context.Background())
if err != nil {
t.Fatalf("couldn't get metadata: %v", err)
}

if diff := testutil.Diff(meta.Schema, schema); diff != "" {
t.Fatalf("got=-, want=+:\n%s", diff)
}

}

func TestIntegration_TableCreateView(t *testing.T) {
if client == nil {
t.Skip("Integration tests skipped")
Expand Down
41 changes: 41 additions & 0 deletions bigquery/schema.go
Expand Up @@ -70,6 +70,41 @@ type FieldSchema struct {

// Describes the nested schema if Type is set to Record.
Schema Schema

// Maximum length of the field for STRING or BYTES type.
//
// It is invalid to set value for types other than STRING or BYTES.
//
// For STRING type, this represents the maximum UTF-8 length of strings
// allowed in the field. For BYTES type, this represents the maximum
// number of bytes in the field.
MaxLength int64

// Precision can be used to constrain the maximum number of
// total digits allowed for NUMERIC or BIGNUMERIC types.
//
// It is invalid to set values for Precision for types other than
// NUMERIC or BIGNUMERIC.
//
// For NUMERIC type, acceptable values for Precision must
// be: 1 ≤ (Precision - Scale) ≤ 29. Values for Scale
// must be: 0 ≤ Scale ≤ 9.
//
// For BIGNUMERIC type, acceptable values for Precision must
// be: 1 ≤ (Precision - Scale) ≤ 38. Values for Scale
// must be: 0 ≤ Scale ≤ 38.
Precision int64

// Scale can be used to constrain the maximum number of digits
// in the fractional part of a NUMERIC or BIGNUMERIC type.
//
// If the Scale value is set, the Precision value must be set as well.
//
// It is invalid to set values for Scale for types other than
// NUMERIC or BIGNUMERIC.
//
// See the Precision field for additional guidance about valid values.
Scale int64
}

func (fs *FieldSchema) toBQ() *bq.TableFieldSchema {
Expand All @@ -78,6 +113,9 @@ func (fs *FieldSchema) toBQ() *bq.TableFieldSchema {
Name: fs.Name,
Type: string(fs.Type),
PolicyTags: fs.PolicyTags.toBQ(),
MaxLength: fs.MaxLength,
Precision: fs.Precision,
Scale: fs.Scale,
}

if fs.Repeated {
Expand Down Expand Up @@ -133,6 +171,9 @@ func bqToFieldSchema(tfs *bq.TableFieldSchema) *FieldSchema {
Required: tfs.Mode == "REQUIRED",
Type: FieldType(tfs.Type),
PolicyTags: bqToPolicyTagList(tfs.PolicyTags),
MaxLength: tfs.MaxLength,
Precision: tfs.Precision,
Scale: tfs.Scale,
}

for _, f := range tfs.Fields {
Expand Down
34 changes: 34 additions & 0 deletions bigquery/schema_test.go
Expand Up @@ -284,6 +284,40 @@ func TestSchemaConversion(t *testing.T) {
fieldSchema("geo", "g", "GEOGRAPHY", false, false, nil),
},
},
{
// constrained
bqSchema: &bq.TableSchema{
Fields: []*bq.TableFieldSchema{
{
Name: "foo",
Type: "STRING",
MaxLength: 0,
Precision: 0,
Scale: 0,
},
{
Name: "bar",
Type: "STRING",
MaxLength: 1,
Precision: 2,
Scale: 3,
},
}},
schema: Schema{
{Name: "foo",
Type: StringFieldType,
MaxLength: 0,
Precision: 0,
Scale: 0,
},
{Name: "bar",
Type: StringFieldType,
MaxLength: 1,
Precision: 2,
Scale: 3,
},
},
},
{
// policy tags
bqSchema: &bq.TableSchema{
Expand Down

0 comments on commit a2330e4

Please sign in to comment.