Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Add support for constraints in databricks_sql_table resource #4205

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

wiatrak2
Copy link

@wiatrak2 wiatrak2 commented Nov 9, 2024

Changes

Hi!

I'd like to extend the databricks_sql_table resource with constraints feature.

Within this pull request I extend the table's resource by allowing user to specify PRIMARY KEY and FOREIGN KEY constraints. I haven't implemented the CHECK constraint, as this one is more tricky and is not allowed during table creation - it can only be added later in the table's lifecycle. If the proposed changed are accepted, I can try to add the implementation for CHECK, as well as cover other constraint options.

I'm aware that the amount of implemented tests may not be satisfying. If this is the case - please let me know and guide my, what kind of tests should be added.

Tests

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

@wiatrak2 wiatrak2 requested review from a team as code owners November 9, 2024 16:46
@wiatrak2 wiatrak2 requested review from mgyucht and removed request for a team November 9, 2024 16:46
@wiatrak2 wiatrak2 changed the title Add support for constraints in databricks_sql_table resource [Feature] Add support for constraints in databricks_sql_table resource Nov 9, 2024
@alexott
Copy link
Contributor

alexott commented Nov 10, 2024

there is a #4155 in progress - can you coordinate with that user to avoid duplications?

@wiatrak2
Copy link
Author

oh, indeed! I see the other user decided on slightly different approach to configuration of the constraint. And seems that the syntax is not compliant with Databricks SQL, maybe that's why there are some test failures. I will ask in that PR if we can somehow cooperate :)

otherwise, is there something I could do to proceed with the feature?

@wiatrak2
Copy link
Author

there is a #4155 in progress - can you coordinate with that user to avoid duplications?

seems the feature should be developed within this PR - I'm open to review and suggestions

@hshahconsulting
Copy link

Could you add functionality for the "RELY" optimization of Primary Keys?

ALTER TABLE customer ADD PRIMARY KEY (c_customer_sk) RELY

Source: https://www.databricks.com/blog/primary-key-and-foreign-key-constraints-are-ga-and-now-enable-faster-queries

Copy link

@hshahconsulting hshahconsulting left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like the RELY optimization support for primary keys, please

@wiatrak2
Copy link
Author

Sure, optional configuration of a constraint with RELY added

Copy link
Contributor

@tanmay-db tanmay-db left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @wiatrak2 for the PR, it looks good, I left some comments, can you please take a look?

@@ -89,6 +99,9 @@ func (ti SqlTableInfo) CustomizeSchema(s *common.CustomizableSchema) *common.Cus
s.SchemaPath("column", "type").SetCustomSuppressDiff(func(k, old, new string, d *schema.ResourceData) bool {
return getColumnType(old) == getColumnType(new)
})
s.SchemaPath("constraint", "type").SetCustomSuppressDiff(func(k, old, new string, d *schema.ResourceData) bool {
return getColumnType(old) == getColumnType(new)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would work because we are essentially checking for case insensitivity and ignoring the mapping here:

	if alias, ok := columnTypeAliases[caseInsensitiveColumnType]; ok {
		return alias
	}

We shouldn't use getColumnType here.

@@ -242,6 +255,39 @@ func (ti *SqlTableInfo) serializeColumnInfos() string {
return strings.Join(columnFragments[:], ", ") // id INT NOT NULL, name STRING, age INT
}

func serializePrimaryKeyConstraint(constraint ConstraintInfo) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we make this as part of the ConstraintInfo struct that we do for getWrappedConstraintName as it will only be used for each constraint info and internally uses ConstraintInfo. getWrappedConstraintName, getWrappedKeyColumnNames and Rely?

We do the same for SqlTableInfo. serializeColumnInfos, serializeColumnInfo

for i, constraint := range ti.Constraints {
if constraint.Type == "PRIMARY KEY" {
constraintFragments[i] = serializePrimaryKeyConstraint(constraint)
} else if constraint.Type == "FOREIGN KEY" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we only support PRIMARY KEY and FOREIGN KEY, we should fail client side if some other value is used.

Copy link

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/terraform

Inputs:

  • PR number: 4205
  • Commit SHA: 22bdf56ecbc89dd531962fb762a58212ecf0e6f2

Checks will be approved automatically on success.

@wiatrak2
Copy link
Author

wiatrak2 commented Nov 14, 2024

Hi @tanmay-db

Thank you for your review. I adjusted the implementation to your comments:

  • regarding CustomizeSchema method - I misunderstood the functionality. Now, I decided to remove any entry for constraints. If you have any suggestions - please let me know
  • I changed the serialize functions to be part of ConstraintInfo struct
  • I strongly agree, that providing any other Constraint type than primary/foreign key on table creation phase should trigger some error, hence I decided to rearrange the statement composing function a bit to handle some error. Moreover, validation on constraint type during table creation allowed to implement the CHECK type as well, that would be consistent do Databricks way of work - i.e. it's not allowed for CREATE TABLE, but you can add it later.

Please let me know what you think about these recent changes

@nkvuong
Copy link
Contributor

nkvuong commented Nov 21, 2024

@wiatrak2 there are CRUD APIs for PK/FK Table Constraints - https://docs.databricks.com/api/workspace/tableconstraints/create, does it make sense to have them as separate resources?

wdyt @tanmay-db ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants