terraform-provider-databricks icon indicating copy to clipboard operation
terraform-provider-databricks copied to clipboard

Remove empty lines from view_definition to avoid unecessary recreation of resources

Open alvaroqueiroz opened this issue 11 months ago • 19 comments

Changes

This PR solves the problem described here: https://github.com/databricks/terraform-provider-databricks/pull/3330

empty new lines on view_definition cause terraform to plan to change the view definition. This PR adds the removal of empty lines to DiffSuppressFunc to avoid this problem

Tests

  • [x] make test run locally
  • [ ] relevant change in docs/ folder
  • [x] covered with integration tests in internal/acceptance
  • [ ] relevant acceptance tests are passing
  • [ ] using Go SDK

image

image

alvaroqueiroz avatar Mar 11 '24 20:03 alvaroqueiroz

hello @mgyucht do you think this is ready for review?

alvaroqueiroz avatar Mar 12 '24 23:03 alvaroqueiroz

My main concern is things like this:

line1\nline2" -> "line1line2

This will break view definitions like this, where it's split between multiple lines:

select col1
from table

will become:

select col1from table

This really should be discussed with the SQL engineering team if it makes sense to do it.

But from the error description, the issue is caused by empty lines, not by newlines, so the replacement should be from this regex \n{1,} -> \n. Also it makes sense to check if it's empty line, vs line with spaces only.

alexott avatar Mar 13 '24 10:03 alexott

hello @alexott, this change would not break line1\nline2" -> "line1line2 I have even a test for that

this will remove both, empty lines and empty lines with spaces, both would cause problems

alvaroqueiroz avatar Mar 13 '24 14:03 alvaroqueiroz

I will add the integration test later today @mgyucht

alvaroqueiroz avatar Mar 13 '24 14:03 alvaroqueiroz

@mgyucht I have added one acceptance test. I have added two steps, one creates the view and the second just adds spaces and empty lines to the view definition. It did not generate alter tables as it would with SuppressDiffWhitespaceChange

Let me know if I should make changes to this test

alvaroqueiroz avatar Mar 19 '24 04:03 alvaroqueiroz

hello @mgyucht do you think it is worth proceeding with the review of this PR or I should close it? I just wanted to fix this bug, but if the team thinks this is not the best solution, I'm open to discussing one that fits

alvaroqueiroz avatar Mar 26 '24 03:03 alvaroqueiroz

@alvaroqueiroz could you resolve the merge conflict for this one?

For this change, could you add a unit test that validates there would not be a change when there is diff between InstanceState and HCL?

nkvuong avatar Mar 27 '24 18:03 nkvuong

done @nkvuong let me know if you need anything else

alvaroqueiroz avatar Mar 27 '24 20:03 alvaroqueiroz

@alvaroqueiroz the conflict resolution for internal/acceptance/sql_table_test.go needs a small fix - could you take a look?

nkvuong avatar Mar 27 '24 20:03 nkvuong

@nkvuong I have synced my fork with the master, the conflict is still present?

alvaroqueiroz avatar Mar 27 '24 20:03 alvaroqueiroz

@alvaroqueiroz build/fmt is already failing - https://github.com/databricks/terraform-provider-databricks/actions/runs/8466731468/job/23199236255?pr=3361

nkvuong avatar Mar 28 '24 13:03 nkvuong

@nkvuong fixed

image

alvaroqueiroz avatar Mar 28 '24 13:03 alvaroqueiroz

this test TestResourceSqlTableUpdateView_IgnoreNewlineInDefinition is failing

nkvuong avatar Mar 28 '24 15:03 nkvuong

@nkvuong I think I'm not setting up the test correctly for some reason. It seems to me that the Update flag will trigger an update regardless of the supressdiff method.

Even If I use the old SuppressDiffWhitespaceChange with just space changes, it will alter the table. Do you have tips on how I could fix my tests?

alvaroqueiroz avatar Apr 02 '24 04:04 alvaroqueiroz

@alvaroqueiroz for unit testing, you could follow the examples of TestCatalogSuppressCaseSensitivity, which tests that the Diff calculated by Terraform is correct

nkvuong avatar Apr 03 '24 17:04 nkvuong

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 83.53%. Comparing base (109361e) to head (8811e29). Report is 8 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3361      +/-   ##
==========================================
+ Coverage   83.51%   83.53%   +0.02%     
==========================================
  Files         178      178              
  Lines       16708    16718      +10     
==========================================
+ Hits        13954    13966      +12     
+ Misses       1901     1900       -1     
+ Partials      853      852       -1     
Files Coverage Δ
catalog/resource_sql_table.go 89.16% <100.00%> (ø)
common/util.go 100.00% <100.00%> (ø)

... and 1 file with indirect coverage changes

codecov-commenter avatar Apr 03 '24 17:04 codecov-commenter

just fyi @nkvuong the test is passing because of this line

I will get the test with ExpectedDiff in place

alvaroqueiroz avatar Apr 03 '24 17:04 alvaroqueiroz

@nkvuong I have tested with ExpectedDiff, I see the same behaviour. Not even the SuppressDiffWhitespaceChange (the one in prod today) works on the tests

image

image

func TestResourceSqlTableUpdateView_IgnoreNewlineInDefinition(t *testing.T) {
	qa.ResourceFixture{
		InstanceState: map[string]string{
			"name":            "barview",
			"catalog_name":    "main",
			"schema_name":     "foo",
			"table_type":      "VIEW",
			"cluster_id":      "existingcluster",
			"view_definition": "SELECT * FROM main.foo.bar",
		},
		ExpectedDiff: map[string]*terraform.ResourceAttrDiff{
			"catalog_name": {
				Old:         "main",
				New:         "main",
				RequiresNew: false,
			},
			"cluster_id": {
				Old:         "existingcluster",
				New:         "existingcluster",
				RequiresNew: false,
			},
			"name": {
				Old:         "barview",
				New:         "barview",
				RequiresNew: false,
			},
			"schema_name": {
				Old:         "foo",
				New:         "foo",
				RequiresNew: false,
			},
			"table_type": {
				Old:         "VIEW",
				New:         "VIEW",
				RequiresNew: false,
			},
			"view_definition": {
				Old:         "SELECT * FROM main.foo.bar",
				New:         "SELECT * FROM main.foo.bar",
				NewComputed: false,
				RequiresNew: false,
				NewRemoved:  false,
				Sensitive:   false,
			},
			"column.#": {
				Old:         "",
				New:         "",
				NewComputed: true,
				RequiresNew: true,
			},
			"properties.%": {
				Old:         "",
				New:         "",
				NewComputed: true,
				RequiresNew: false,
			},
		},
		HCL: `
		name               = "barview"
		catalog_name       = "main"
		schema_name        = "foo"
		table_type         = "VIEW"
		cluster_id         = "existingcluster"
		view_definition    = "SELECT * FROM main.foo.bar "
		`,
		Resource: ResourceSqlTable(),
		ID:       "main.foo.barview",
	}.ApplyNoError(t)
}

alvaroqueiroz avatar Apr 08 '24 22:04 alvaroqueiroz

@alvaroqueiroz Appreciate your work. I see a lot of value in this fix, as this unnecessary detection of changes increases the apply time significantly. Also, the recreation of the views with no change is not desirable, as it could run into contention with active ETLs that consume data from the views.

vsluc avatar Apr 15 '24 17:04 vsluc