Allow to do a change_table to change partition key#64
Allow to do a change_table to change partition key#64louiseGrandjonc wants to merge 12 commits intomasterfrom
Conversation
74a54d6 to
0030104
Compare
0030104 to
987337a
Compare
… there is a change_table :partition_key
| "ON kcu.constraint_name = tco.constraint_name " \ | ||
| "AND kcu.constraint_schema = tco.constraint_schema "\ | ||
| "WHERE tco.constraint_type = 'PRIMARY KEY' " \ | ||
| "AND tco.constraint_name = '#{table_name}_pkey'") |
There was a problem hiding this comment.
Can we use a bind parameter here, instead of string substitution?
Whilst its unlikely that someone will do SQL injection here, it seems better to avoid problems with table_name called '; DROP TABLE xyz; SELECT '
| columns_result.values.each do |c| columns.push(c[0]) end | ||
|
|
||
| if columns.length != pkey_columns.length | ||
| execute "ALTER TABLE #{table_name} DROP CONSTRAINT IF EXISTS #{table_name}_pkey" |
There was a problem hiding this comment.
Same here regarding SQL injection - I think there are methods to escape identifier names in ActiveRecord::Base that we can use
There was a problem hiding this comment.
Actually, I tried looking into it, the method to sanitize raw sql is sanitize_sql_array, except here, we are taking the name of the table in the ALTER TABLE which ends up like this:
query = ActiveRecord::Base::sanitize_sql_array(["ALTER TABLE $1 DROP CONSTRAINT IF EXISTS $2_pkey;", table_name, table_name])
execute(query)
And this triggers errors because SQL doesn't suppose that format
If you have an idea how to do change the queries, let me know
| ret = orig_create_table(table_name, options.except(:partition_key), &block) | ||
| if options[:partition_key] && options[:partition_key].to_s != 'id' | ||
| execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{table_name}_pkey" | ||
| execute "ALTER TABLE #{table_name} ADD PRIMARY KEY(id, \"#{options[:partition_key]}\")" |
There was a problem hiding this comment.
Of course, to be fair my own code was not up to my comments :-)
There was a problem hiding this comment.
haha, noted, I'll work on avoiding SQL injection ;)
spec/schema.rb
Outdated
| create_reference_table :categories | ||
|
|
||
| change_table :project_categories, partition_key: :account_id do |t| | ||
| end |
There was a problem hiding this comment.
I think we can not pass the block at all, unless that throws an error:
change_table :project_categories, partition_key: :account_id|
|
||
| if columns_result.present? | ||
| columns = [] | ||
| columns_result.values.each do |c| columns.push(c[0]) end |
There was a problem hiding this comment.
For one liners usually in Ruby you'd use the { .. } syntax:
columns_result.values.each { |c| columns.push(c[0]) }There was a problem hiding this comment.
is there anyway to do this without initializing a constant? in python you can do
columns = [e[0] for e in columns_result.values]
There was a problem hiding this comment.
Yes, you could do it like this:
columns = columns_result.values.map { |c| c[0] } or without the block, utilizing the fact that there is a first method on arrays:
columns = columns_result.values.map(&:first)…f the structure.sql
93aa622 to
419f234
Compare
|
Hi, are you planning to merge this? |
|
No, both Louis & Lukas are no longer with Citus If someone else wants this to get through they can create a new PR based on this one |
This PR allows a user to create a migration to do
Which will create the primary key (partittion_key, id).
Things this PR does not do: