Skip to content

Commit

Permalink
fix: external tables issues (#2334)
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-jcieslak authored Jan 11, 2024
1 parent 4fef709 commit ae41691
Show file tree
Hide file tree
Showing 20 changed files with 761 additions and 192 deletions.
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export SKIP_EMAIL_INTEGRATION_TESTS=true
export SKIP_EXTERNAL_TABLE_TEST=true
export SKIP_NOTIFICATION_INTEGRATION_TESTS=true
export SKIP_SAML_INTEGRATION_TESTS=true
export SKIP_STREAM_TEST=true
Expand Down
1 change: 1 addition & 0 deletions docs/resources/external_table.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ resource "snowflake_external_table" "external_table" {
- `partition_by` (List of String) Specifies any partition columns to evaluate for the external table.
- `pattern` (String) Specifies the file names and/or paths on the external stage to match.
- `refresh_on_create` (Boolean) Specifies weather to refresh when an external table is created.
- `table_format` (String) Identifies the external table table type. For now, only "delta" for Delta Lake table format is supported.
- `tag` (Block List, Deprecated) Definitions of a tag to associate with the resource. (see [below for nested schema](#nestedblock--tag))

### Read-Only
Expand Down
87 changes: 63 additions & 24 deletions pkg/resources/external_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -30,6 +32,13 @@ var externalTableSchema = map[string]*schema.Schema{
ForceNew: true,
Description: "The database in which to create the external table.",
},
"table_format": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: `Identifies the external table table type. For now, only "delta" for Delta Lake table format is supported.`,
ValidateFunc: validation.StringInSlice([]string{"delta"}, true),
},
"column": {
Type: schema.TypeList,
Required: true,
Expand Down Expand Up @@ -152,7 +161,6 @@ func CreateExternalTable(d *schema.ResourceData, meta any) error {
id := sdk.NewSchemaObjectIdentifier(database, schema, name)
location := d.Get("location").(string)
fileFormat := d.Get("file_format").(string)
req := sdk.NewCreateExternalTableRequest(id, location).WithRawFileFormat(&fileFormat)

tableColumns := d.Get("column").([]any)
columnRequests := make([]*sdk.ExternalTableColumnRequest, len(tableColumns))
Expand All @@ -161,51 +169,82 @@ func CreateExternalTable(d *schema.ResourceData, meta any) error {
for key, val := range col.(map[string]any) {
columnDef[key] = val.(string)
}

name := columnDef["name"]
dataTypeString := columnDef["type"]
dataType, err := sdk.ToDataType(dataTypeString)
if err != nil {
return fmt.Errorf(`failed to parse datatype: %s`, dataTypeString)
}
as := columnDef["as"]
columnRequests[i] = sdk.NewExternalTableColumnRequest(name, dataType, as)
columnRequests[i] = sdk.NewExternalTableColumnRequest(
columnDef["name"],
sdk.DataType(columnDef["type"]),
columnDef["as"],
)
}
req.WithColumns(columnRequests)

req.WithAutoRefresh(sdk.Bool(d.Get("auto_refresh").(bool)))
req.WithRefreshOnCreate(sdk.Bool(d.Get("refresh_on_create").(bool)))
req.WithCopyGrants(sdk.Bool(d.Get("copy_grants").(bool)))
autoRefresh := sdk.Bool(d.Get("auto_refresh").(bool))
refreshOnCreate := sdk.Bool(d.Get("refresh_on_create").(bool))
copyGrants := sdk.Bool(d.Get("copy_grants").(bool))

var partitionBy []string
if v, ok := d.GetOk("partition_by"); ok {
partitionBy := expandStringList(v.([]any))
req.WithPartitionBy(partitionBy)
partitionBy = expandStringList(v.([]any))
}

var pattern *string
if v, ok := d.GetOk("pattern"); ok {
req.WithPattern(sdk.String(v.(string)))
pattern = sdk.String(v.(string))
}

var awsSnsTopic *string
if v, ok := d.GetOk("aws_sns_topic"); ok {
req.WithAwsSnsTopic(sdk.String(v.(string)))
awsSnsTopic = sdk.String(v.(string))
}

var comment *string
if v, ok := d.GetOk("comment"); ok {
req.WithComment(sdk.String(v.(string)))
comment = sdk.String(v.(string))
}

var tagAssociationRequests []*sdk.TagAssociationRequest
if _, ok := d.GetOk("tag"); ok {
tagAssociations := getPropertyTags(d, "tag")
tagAssociationRequests := make([]*sdk.TagAssociationRequest, len(tagAssociations))
tagAssociationRequests = make([]*sdk.TagAssociationRequest, len(tagAssociations))
for i, t := range tagAssociations {
tagAssociationRequests[i] = sdk.NewTagAssociationRequest(t.Name, t.Value)
}
req.WithTag(tagAssociationRequests)
}

if err := client.ExternalTables.Create(ctx, req); err != nil {
return err
switch {
case d.Get("table_format").(string) == "delta":
err := client.ExternalTables.CreateDeltaLake(
ctx,
sdk.NewCreateDeltaLakeExternalTableRequest(id, location).
WithColumns(columnRequests).
WithPartitionBy(partitionBy).
WithRefreshOnCreate(refreshOnCreate).
WithAutoRefresh(autoRefresh).
WithRawFileFormat(&fileFormat).
WithCopyGrants(copyGrants).
WithComment(comment).
WithTag(tagAssociationRequests),
)
if err != nil {
return err
}
default:
err := client.ExternalTables.Create(
ctx,
sdk.NewCreateExternalTableRequest(id, location).
WithColumns(columnRequests).
WithPartitionBy(partitionBy).
WithRefreshOnCreate(refreshOnCreate).
WithAutoRefresh(autoRefresh).
WithPattern(pattern).
WithRawFileFormat(&fileFormat).
WithAwsSnsTopic(awsSnsTopic).
WithCopyGrants(copyGrants).
WithComment(comment).
WithTag(tagAssociationRequests),
)
if err != nil {
return err
}
}

d.SetId(helpers.EncodeSnowflakeID(id))

return ReadExternalTable(d, meta)
Expand Down
Loading

0 comments on commit ae41691

Please sign in to comment.