Skip to content

Commit

Permalink
fix: Fix show by id for external functions (#2531)
Browse files Browse the repository at this point in the history
- Fix show by id for external functions.
- Correction to the documentation
(https://docs.snowflake.com/en/sql-reference/sql/show-external-functions#syntax)
requested internally.

References: #2528
  • Loading branch information
sfc-gh-asawicki authored Feb 26, 2024
1 parent 677a12b commit d910a84
Show file tree
Hide file tree
Showing 7 changed files with 116 additions and 3 deletions.
74 changes: 74 additions & 0 deletions pkg/resources/external_function_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,33 @@ func TestAcc_ExternalFunction_migrateFromVersion085(t *testing.T) {
})
}

// Proves issue https://github.com/Snowflake-Labs/terraform-provider-snowflake/issues/2528.
// The problem originated from ShowById without IN clause. There was no IN clause in the docs at the time.
// It was raised with the appropriate team in Snowflake.
func TestAcc_ExternalFunction_issue2528(t *testing.T) {
accName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
secondSchema := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))

resourceName := "snowflake_external_function.f"

resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
PreCheck: func() { acc.TestAccPreCheck(t) },
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.RequireAbove(tfversion.Version1_5_0),
},
CheckDestroy: nil,
Steps: []resource.TestStep{
{
Config: externalFunctionConfigIssue2528(acc.TestDatabaseName, acc.TestSchemaName, accName, secondSchema),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "name", accName),
),
},
},
})
}

func externalFunctionConfig(database string, schema string, name string) string {
return fmt.Sprintf(`
resource "snowflake_api_integration" "test_api_int" {
Expand Down Expand Up @@ -313,3 +340,50 @@ resource "snowflake_external_function" "f" {
`, database, schema, name)
}

func externalFunctionConfigIssue2528(database string, schema string, name string, schema2 string) string {
return fmt.Sprintf(`
resource "snowflake_api_integration" "test_api_int" {
name = "%[3]s"
api_provider = "aws_api_gateway"
api_aws_role_arn = "arn:aws:iam::000000000001:/role/test"
api_allowed_prefixes = ["https://123456.execute-api.us-west-2.amazonaws.com/prod/"]
enabled = true
}
resource "snowflake_schema" "s2" {
database = "%[1]s"
name = "%[4]s"
}
resource "snowflake_external_function" "f" {
name = "%[3]s"
database = "%[1]s"
schema = "%[2]s"
arg {
name = "SNS_NOTIF"
type = "OBJECT"
}
return_type = "VARIANT"
return_behavior = "VOLATILE"
api_integration = snowflake_api_integration.test_api_int.name
url_of_proxy_and_resource = "https://123456.execute-api.us-west-2.amazonaws.com/prod/test_func"
}
resource "snowflake_external_function" "f2" {
depends_on = [snowflake_schema.s2]
name = "%[3]s"
database = "%[1]s"
schema = "%[4]s"
arg {
name = "SNS_NOTIF"
type = "OBJECT"
}
return_type = "VARIANT"
return_behavior = "VOLATILE"
api_integration = snowflake_api_integration.test_api_int.name
url_of_proxy_and_resource = "https://123456.execute-api.us-west-2.amazonaws.com/prod/test_func"
}
`, database, schema, name, schema2)
}
7 changes: 5 additions & 2 deletions pkg/sdk/external_functions_dto_builders_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/sdk/external_functions_dto_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ type ExternalFunctionUnsetRequest struct {

type ShowExternalFunctionRequest struct {
Like *Like
In *In
}

type DescribeExternalFunctionRequest struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/sdk/external_functions_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ type ShowExternalFunctionOptions struct {
show bool `ddl:"static" sql:"SHOW"`
externalFunctions bool `ddl:"static" sql:"EXTERNAL FUNCTIONS"`
Like *Like `ddl:"keyword" sql:"LIKE"`
In *In `ddl:"keyword" sql:"IN"`
}

type externalFunctionRow struct {
Expand Down
9 changes: 9 additions & 0 deletions pkg/sdk/external_functions_gen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,15 @@ func TestExternalFunctions_Show(t *testing.T) {
}
assertOptsValidAndSQLEquals(t, opts, `SHOW EXTERNAL FUNCTIONS LIKE 'pattern'`)
})

t.Run("show with in", func(t *testing.T) {
id := RandomDatabaseObjectIdentifier()
opts := defaultOpts()
opts.In = &In{
Schema: id,
}
assertOptsValidAndSQLEquals(t, opts, `SHOW EXTERNAL FUNCTIONS IN SCHEMA %s`, id.FullyQualifiedName())
})
}

func TestExternalFunctions_Describe(t *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion pkg/sdk/external_functions_impl_gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ func (v *externalFunctions) Show(ctx context.Context, request *ShowExternalFunct
}

func (v *externalFunctions) ShowByID(ctx context.Context, id SchemaObjectIdentifier, arguments []DataType) (*ExternalFunction, error) {
externalFunctions, err := v.Show(ctx, NewShowExternalFunctionRequest().WithLike(&Like{Pattern: String(id.Name())}))
externalFunctions, err := v.Show(ctx, NewShowExternalFunctionRequest().
WithIn(&In{Schema: NewDatabaseObjectIdentifier(id.DatabaseName(), id.SchemaName())}).
WithLike(&Like{Pattern: String(id.Name())}))
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -157,6 +159,7 @@ func (r *AlterExternalFunctionRequest) toOpts() *AlterExternalFunctionOptions {
func (r *ShowExternalFunctionRequest) toOpts() *ShowExternalFunctionOptions {
opts := &ShowExternalFunctionOptions{
Like: r.Like,
In: r.In,
}
return opts
}
Expand Down
22 changes: 22 additions & 0 deletions pkg/sdk/testint/external_functions_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,28 @@ func TestInt_ExternalFunctions(t *testing.T) {
require.NotContains(t, es, *e2)
})

t.Run("show external function: with in", func(t *testing.T) {
otherDb, otherDbCleanup := createDatabase(t, testClient(t))
t.Cleanup(otherDbCleanup)

e1 := createExternalFunction(t, sdk.DataTypeVARCHAR)

es, err := client.ExternalFunctions.Show(ctx, sdk.NewShowExternalFunctionRequest().WithIn(&sdk.In{Schema: sdk.NewDatabaseObjectIdentifier(databaseTest.Name, schemaTest.Name)}))
require.NoError(t, err)

require.Contains(t, es, *e1)

es, err = client.ExternalFunctions.Show(ctx, sdk.NewShowExternalFunctionRequest().WithIn(&sdk.In{Database: sdk.NewAccountObjectIdentifier(databaseTest.Name)}))
require.NoError(t, err)

require.Contains(t, es, *e1)

es, err = client.ExternalFunctions.Show(ctx, sdk.NewShowExternalFunctionRequest().WithIn(&sdk.In{Database: otherDb.ID()}))
require.NoError(t, err)

require.Empty(t, es)
})

t.Run("show external function: no matches", func(t *testing.T) {
es, err := client.ExternalFunctions.Show(ctx, sdk.NewShowExternalFunctionRequest().WithLike(&sdk.Like{Pattern: sdk.String(random.String())}))
require.NoError(t, err)
Expand Down

0 comments on commit d910a84

Please sign in to comment.