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

Support setting table and column comments to NULL #345

Merged
merged 11 commits into from
Apr 29, 2024

Conversation

andrew-farries
Copy link
Collaborator

@andrew-farries andrew-farries commented Apr 23, 2024

Build on #344 to allow removing column comments by setting them to null.

Make use of omissis/go-jsonschema#220 and use the nullable package so that it's possible to distingush between a missing comment field and one that is explicitly set to null.

With omissis/go-jsonschema#220 not being part of a release yet, use a custom build of go-jsonschema. It should be possible to switch back to the official release images once omissis/go-jsonschema#220 is part of a release.

Without this change it becomes impossible to remove a comment from a column using the 'set comment' 'alter column' sub-operation (#344).

@exekias
Copy link
Member

exekias commented Apr 23, 2024

uhm, I think the need for quotes is quite unexpected as a user. Wouldn't be enough to pass a "comment": null JSON value?

@andrew-farries
Copy link
Collaborator Author

andrew-farries commented Apr 23, 2024

Wouldn't be enough to pass a "comment": null JSON value?

Passing "comment": null would mean that we can't easily distinguish between a comment field that is unset vs one that is explicitly set to NULL. In an 'alter column' operation therefore, we wouldn't know whether to set the comment to NULL or leave it unchanged. This is a common problem with Go JSON unmarshalling (see eg here).

pgroll already requires quoted literal strings when setting column DEFAULT values; here the user may set the column DEFAULT to some function call (eg now() for timestamp columns) so pgroll can't assume that all DEFAULTs should be quoted so it is left to the user to do so.

In the case of comments, the only two values allowed are literal strings or NULL. So arguably it's more surprising that non-NULL comments have to be single quoted strings than it is when setting a DEFAULT where arbitrary expressions are also allowed.

We have some options:

  • Accept the changes in this PR and require comment fields to be single-quoted strings or a bare NULL.
  • Close this PR and accept that comments can't be removed by alter column statements, only set to the empty string (removal of a comment could still be done with a raw SQL migration)
  • Invest more time in coming up with a solution to allow distinguishing explicitly set to NULL comments vs missing fields (eg using the nulllable package). This will be complicated by the fact that our operation types are generated from the JSON schema so doesn't allow us much control over the type of the comment field in an OpAlterColumn.

@andrew-farries
Copy link
Collaborator Author

After some more experimentation, allowing "comment": null to remove a comment field will work as long as we can specify the type of the OpAlterColumn.Comment field as Nullable[string] (using the nullable package).

It requires an upstream change to go-jsonschema in order to emit the nullable.Nullable type correctly from the schema.json file.

This would mean users could specify either:

comment: null

or

comment: "some string"

without having to enclose "some string" in single quotes. This makes it inconsistent with how string literals are specified with DEFAULT values, but perhaps less surprising.

@andrew-farries andrew-farries changed the base branch from main to add-alter-column-comment-sub-op April 26, 2024 11:04
@andrew-farries andrew-farries marked this pull request as draft April 26, 2024 11:12
@andrew-farries andrew-farries removed the request for review from exekias April 26, 2024 11:12
@exekias
Copy link
Member

exekias commented Apr 26, 2024

I like this one! Wondering if we could do the same for others. roping @eemmiillyy @SferaDev for thoughts on the json schema

schema.json Outdated
Comment on lines 162 to 167
"type": "string",
"goJSONSchema": {
"imports": ["github.com/oapi-codegen/nullable"],
"nillable": true,
"type": "nullable.Nullable[string]"
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The problem with using type: ["string", "null"] is that it generates the Go type:

Comment *string `json:"name"

which doesn't allow us to distinguish between the case where the 'alter column' comment field is specified and set to null, vs left unspecified.

See #345 (comment)

Using nullable.Nullable allows us to distinguish the 'set to null' and the 'unspecified' cases.

schema.json Outdated
@@ -159,7 +159,12 @@
},
"comment": {
"description": "New comment on the column",
"type": "string"
"type": "string",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
"type": "string",
"type": ["string", "null"],

@andrew-farries andrew-farries force-pushed the allow-setting-comment-to-null branch 4 times, most recently from 0dfcd2a to 9f74b91 Compare April 28, 2024 16:41
@andrew-farries
Copy link
Collaborator Author

andrew-farries commented Apr 28, 2024

I think this is ready now. The upstream change to go-jsonschema has landed: omissis/go-jsonschema#220.

I've updated the PR description:


Build on #344 to allow removing column comments by setting them to null.

Make use of omissis/go-jsonschema#220 and use the nullable package so that it's possible to distingush between a missing comment field and one that is explicitly set to null.

With omissis/go-jsonschema#220 not being part of a release yet, use a custom build of go-jsonschema. It should be possible to switch back to the official release images once that PR is part of a release.

Without this change it becomes impossible to remove a comment from a column using the 'set comment' 'alter column' sub-operation (#344).

@andrew-farries
Copy link
Collaborator Author

Wondering if we could do the same for others

What do you mean by this @exekias? I don't think the same approach makes sense for setting default values for the reasons described in #345 (comment).

It makes sense for comment because there are only two allowed values: string literals or null.

@andrew-farries andrew-farries marked this pull request as ready for review April 28, 2024 16:58
@andrew-farries
Copy link
Collaborator Author

We also need to approve the PR on which this one is based: #344

Base automatically changed from add-alter-column-comment-sub-op to main April 29, 2024 09:40
Ensure that leaving the comment unspecified in an alter column statement
does not change the comment.
Allow unrecognized properties in the schema definition. This allows the
`goJSONSchema` extension keyword.

See:

https://ajv.js.org/strict-mode.html#prohibit-ignored-keywords
@andrew-farries andrew-farries merged commit 4f0a715 into main Apr 29, 2024
44 checks passed
@andrew-farries andrew-farries deleted the allow-setting-comment-to-null branch April 29, 2024 12:23
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.

None yet

3 participants