Skip to content

Commit a395f6b

Browse files
danielwestendorftylerCaineRhodes
authored andcommitted
Add support for force CREATE FUNCTION (PNixx#146)
* Switch from `CREATE FUNCTION` to `CREATE OR REPLACE FUNCTION` In a rails app, with existing Clickhouse schema w/a function defined, a `rails db:schema:load` will not always succeed; this is because the function may already exist. ``` Code: 609. DB::Exception: User-defined function 'uuid7ToDateTime' already exists. (FUNCTION_ALREADY_EXISTS) (version 23.9.6.20 (official build)) ```
1 parent 1a95e3a commit a395f6b

File tree

5 files changed

+12
-5
lines changed

5 files changed

+12
-5
lines changed

lib/active_record/connection_adapters/clickhouse_adapter.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,8 @@ def create_table(table_name, **options, &block)
356356
end
357357
end
358358

359-
def create_function(name, body)
360-
fd = "CREATE FUNCTION #{apply_cluster(quote_table_name(name))} AS #{body}"
359+
def create_function(name, body, **options)
360+
fd = "CREATE#{' OR REPLACE' if options[:force]} FUNCTION #{apply_cluster(quote_table_name(name))} AS #{body}"
361361
do_execute(fd, format: nil)
362362
end
363363

lib/clickhouse-activerecord/schema_dumper.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def function(function, stream)
112112
stream.puts " # FUNCTION: #{function}"
113113
sql = @connection.show_create_function(function)
114114
stream.puts " # SQL: #{sql}" if sql
115-
stream.puts " create_function \"#{function}\", \"#{sql.gsub(/^CREATE FUNCTION (.*?) AS/, '').strip}\"" if sql
115+
stream.puts " create_function \"#{function}\", \"#{sql.gsub(/^CREATE FUNCTION (.*?) AS/, '').strip}\", force: true" if sql
116116
end
117117

118118
def format_options(options)

spec/cluster/migration_spec.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@
7070
let(:directory) { 'dsl_create_function' }
7171

7272
it 'creates a function' do
73+
ActiveRecord::Base.connection.do_execute('CREATE FUNCTION forced_fun AS (x, k, b) -> k*x + b', format: nil)
74+
7375
subject
7476

75-
expect(ActiveRecord::Base.connection.functions).to match_array(['some_fun'])
77+
expect(ActiveRecord::Base.connection.functions).to match_array(['some_fun', 'forced_fun'])
78+
expect(ActiveRecord::Base.connection.show_create_function('forced_fun').chomp).to eq('CREATE FUNCTION forced_fun AS (x, y) -> (x + y)')
7679
end
7780
end
7881
end

spec/fixtures/migrations/dsl_create_function/1_create_some_function.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
class CreateSomeFunction < ActiveRecord::Migration[7.1]
44
def up
55
create_function :some_fun, "(x,y) -> x + y"
6+
create_function :forced_fun, "(x,y) -> x + y", force: true
67
end
78
end

spec/single/migration_spec.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,12 @@
369369
context 'dsl' do
370370
let(:directory) { 'dsl_create_function' }
371371
it 'creates a function' do
372+
ActiveRecord::Base.connection.do_execute('CREATE FUNCTION forced_fun AS (x, k, b) -> k*x + b', format: nil)
373+
372374
subject
373375

374-
expect(ActiveRecord::Base.connection.functions).to match_array(['some_fun'])
376+
expect(ActiveRecord::Base.connection.functions).to match_array(['some_fun', 'forced_fun'])
377+
expect(ActiveRecord::Base.connection.show_create_function('forced_fun').chomp).to eq('CREATE FUNCTION forced_fun AS (x, y) -> (x + y)')
375378
end
376379
end
377380
end

0 commit comments

Comments
 (0)