-
Notifications
You must be signed in to change notification settings - Fork 73
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
sql2pgroll: Support set and drop column defaults #526
Conversation
// | ||
// to an OpDropColumn operation. | ||
// to an OpAlterColumn operation. | ||
func convertAlterTableSetColumnDefault(stmt *pgq.AlterTableStmt, cmd *pgq.AlterTableCmd) (migrations.Operation, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since OpAlterColumn
only supports nullable string defaults, this will fail for any other kind of default for example non strings or the value of a function call.
In those cases should we fall back to raw sql?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like if the new default value is a constant, we can support these types:
type A_Const struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Types that are assignable to Val:
//
// *A_Const_Ival
// *A_Const_Fval
// *A_Const_Boolval
// *A_Const_Sval
// *A_Const_Bsval
Val isA_Const_Val `protobuf_oneof:"val"`
Isnull bool `protobuf:"varint,10,opt,name=isnull,proto3" json:"isnull,omitempty"`
Location int32 `protobuf:"varint,11,opt,name=location,proto3" json:"location,omitempty"`
}
And then convert them to a string
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've done this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good start 👍
This won't work for all types of column default though:
-- integers
ALTER TABLE foo ALTER COLUMN bar SET DEFAULT 2
-- booleans
ALTER TABLE foo ALTER COLUMN bar SET DEFAULT true
-- floating point values
ALTER TABLE foo ALTER COLUMN bar SET DEFAULT 2.0
-- bitstrings
ALTER TABLE foo ALTER COLUMN bar SET DEFAULT B'10101010'
-- function calls
ALTER TABLE foo ALTER COLUMN bar SET DEFAULT NOW()
These cases all have a different AST structure and need to be handled separately. In general a column DEFAULT
can be an expression of arbitrary complexity, such as:
ALTER TABLE foo ALTER COLUMN bar SET DEFAULT (CASE WHEN EXTRACT(DOW FROM CURRENT_TIMESTAMP) IN (0, 6) THEN 1 ELSE 5 END)
In the latter case I think we need to make changes to the pg_query_go
dependency to support deparsing arbitrary SQL expressions, rather than only the full SQL statements that it currently supports.
For now we should aim to convert DEFAULT
expressions where the expression is a simple literal:
- integer
- boolean
- floating point
- bit string
We can leave handling function calls and more complex SQL until later.
Cool, that's exactly what I did 😄 I'll throw in a test case where it's a function value, for example |
@andrew-farries Ok, I think I've handled all the cases now. |
Support translating the following alter table statements into pgroll operations:
For cases where the default is set to something other than a simple literal, we fall back to raw SQL.