Skip to content

Commit

Permalink
feat: Allow in-place renaming of Snowflake tables (#904)
Browse files Browse the repository at this point in the history
  • Loading branch information
nafarlee committed Mar 22, 2022
1 parent 17de20f commit 6ac5188
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
11 changes: 9 additions & 2 deletions pkg/resources/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ var tableSchema = map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Specifies the identifier for the table; must be unique for the database and schema in which the table is created.",
},
"schema": {
Expand Down Expand Up @@ -596,6 +595,15 @@ func UpdateTable(d *schema.ResourceData, meta interface{}) error {
builder := snowflake.Table(tableName, dbName, schema)

db := meta.(*sql.DB)
if d.HasChange("name") {
name := d.Get("name")
q := builder.Rename(name.(string))
err := snowflake.Exec(db, q)
if err != nil {
return errors.Wrapf(err, "error updating table name on %v", d.Id())
}
d.SetId(fmt.Sprintf("%v|%v|%v", dbName, schema, name.(string)))
}
if d.HasChange("comment") {
comment := d.Get("comment")
q := builder.ChangeComment(comment.(string))
Expand All @@ -604,7 +612,6 @@ func UpdateTable(d *schema.ResourceData, meta interface{}) error {
return errors.Wrapf(err, "error updating table comment on %v", d.Id())
}
}

if d.HasChange("cluster_by") {
cb := expandStringList(d.Get("cluster_by").([]interface{}))

Expand Down
63 changes: 63 additions & 0 deletions pkg/resources/table_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1208,3 +1208,66 @@ resource "snowflake_table" "test_table" {
`
return fmt.Sprintf(s, name, name, name, name)
}

func TestAcc_TableRename(t *testing.T) {
accName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
oldTableName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
newTableName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
Steps: []resource.TestStep{
{
Config: tableConfigWithName(accName, oldTableName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("snowflake_table.test_table", "name", oldTableName),
resource.TestCheckResourceAttr("snowflake_table.test_table", "database", accName),
resource.TestCheckResourceAttr("snowflake_table.test_table", "schema", accName),
resource.TestCheckResourceAttr("snowflake_table.test_table", "data_retention_days", "1"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "change_tracking", "false"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "column.#", "1"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "column.0.name", "column1"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "column.0.type", "VARIANT"),
resource.TestCheckNoResourceAttr("snowflake_table.test_table", "primary_key"),
),
},
{
Config: tableConfigWithName(accName, newTableName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("snowflake_table.test_table", "name", newTableName),
resource.TestCheckResourceAttr("snowflake_table.test_table", "database", accName),
resource.TestCheckResourceAttr("snowflake_table.test_table", "schema", accName),
resource.TestCheckResourceAttr("snowflake_table.test_table", "data_retention_days", "1"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "change_tracking", "false"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "column.#", "1"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "column.0.name", "column1"),
resource.TestCheckResourceAttr("snowflake_table.test_table", "column.0.type", "VARIANT"),
resource.TestCheckNoResourceAttr("snowflake_table.test_table", "primary_key"),
),
},
},
})
}

func tableConfigWithName(name string, tableName string) string {
s := `
resource "snowflake_database" "test_database" {
name = "%s"
}
resource "snowflake_schema" "test_schema" {
name = "%s"
database = snowflake_database.test_database.name
}
resource "snowflake_table" "test_table" {
database = snowflake_database.test_database.name
schema = snowflake_schema.test_schema.name
name = "%s"
column {
name = "column1"
type = "VARIANT"
}
}
`
return fmt.Sprintf(s, name, name, tableName)
}
6 changes: 6 additions & 0 deletions pkg/snowflake/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,12 @@ func (tb *TableBuilder) ShowPrimaryKeys() string {
return fmt.Sprintf(`SHOW PRIMARY KEYS IN TABLE %s`, tb.QualifiedName())
}

func (tb *TableBuilder) Rename(newName string) string {
oldName := tb.QualifiedName()
tb.name = newName
return fmt.Sprintf(`ALTER TABLE %s RENAME TO %s`, oldName, tb.QualifiedName())
}

type table struct {
CreatedOn sql.NullString `db:"created_on"`
TableName sql.NullString `db:"name"`
Expand Down
6 changes: 6 additions & 0 deletions pkg/snowflake/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,9 @@ func TestTableUnsetTag(t *testing.T) {
s := Table("test_table", "test_db", "test_schema")
r.Equal(s.UnsetTag(TagValue{Name: "tag", Schema: "test_schema", Database: "test_db"}), `ALTER TABLE "test_db"."test_schema"."test_table" UNSET TAG "test_db"."test_schema"."tag"`)
}

func TestTableRename(t *testing.T) {
r := require.New(t)
s := Table("test_table1", "test_db", "test_schema")
r.Equal(s.Rename("test_table2"), `ALTER TABLE "test_db"."test_schema"."test_table1" RENAME TO "test_db"."test_schema"."test_table2"`)
}

0 comments on commit 6ac5188

Please sign in to comment.