diff --git a/lib/active_record/connection_adapters/clickhouse_adapter.rb b/lib/active_record/connection_adapters/clickhouse_adapter.rb index fd87e88a..e2e0becf 100644 --- a/lib/active_record/connection_adapters/clickhouse_adapter.rb +++ b/lib/active_record/connection_adapters/clickhouse_adapter.rb @@ -142,6 +142,11 @@ def initialize(config_or_deprecated_connection, deprecated_logger = nil, depreca connect end + # Return ClickHouse server version + def server_version + @server_version ||= do_system_execute('SELECT version()')['data'][0][0] + end + # Savepoints are not supported, noop def create_savepoint(name) end @@ -277,9 +282,11 @@ def column_name_for_operation(operation, node) # :nodoc: # SCHEMA STATEMENTS ======================================== def primary_keys(table_name) - structure = do_system_execute("SHOW COLUMNS FROM `#{table_name}`") - structure['data'].select {|m| m[3]&.include?('PRI') }.pluck(0) - rescue ActiveRecord::ActiveRecordError => e + if server_version.to_f >= 23.4 + structure = do_system_execute("SHOW COLUMNS FROM `#{table_name}`") + return structure['data'].select {|m| m[3]&.include?('PRI') }.pluck(0) + end + pk = table_structure(table_name).first return ['id'] if pk.present? && pk[0] == 'id' [] diff --git a/spec/single/model_spec.rb b/spec/single/model_spec.rb index 1fb6cf83..6283033e 100644 --- a/spec/single/model_spec.rb +++ b/spec/single/model_spec.rb @@ -10,6 +10,11 @@ class Model < ActiveRecord::Base self.table_name = 'sample' has_many :joins, class_name: 'ModelJoin', primary_key: 'event_name' end + class ModelPk < ActiveRecord::Base + self.table_name = 'sample' + self.primary_key = 'event_name' + end + IS_NEW_CLICKHOUSE_SERVER = Model.connection.server_version.to_f >= 23.4 let(:date) { Date.today } @@ -20,8 +25,10 @@ class Model < ActiveRecord::Base quietly { ActiveRecord::MigrationContext.new(migrations_dir).up } end - it 'detect primary key' do - expect(Model.primary_key).to eq('event_name') + if IS_NEW_CLICKHOUSE_SERVER + it "detect primary key" do + expect(Model.primary_key).to eq('event_name') + end end describe '#do_execute' do @@ -80,7 +87,11 @@ class Model < ActiveRecord::Base it 'update model with primary key' do expect { - Model.first.update!(event_value: 2) + if IS_NEW_CLICKHOUSE_SERVER + Model.first.update!(event_value: 2) + else + ModelPk.first.update!(event_value: 2) + end }.to_not raise_error end end @@ -96,7 +107,11 @@ class Model < ActiveRecord::Base it 'destroy model with primary key' do expect { - Model.first.destroy! + if IS_NEW_CLICKHOUSE_SERVER + Model.first.destroy! + else + ModelPk.first.destroy! + end }.to_not raise_error end end @@ -117,8 +132,13 @@ class Model < ActiveRecord::Base it 'select' do Model.create!(event_name: 'some event 1', date: 1.day.ago) Model.create!(event_name: 'some event 2', date: 2.day.ago) - expect(Model.all.reverse_order!.to_sql).to eq('SELECT sample.* FROM sample ORDER BY sample.event_name DESC') - expect(Model.all.reverse_order!.map(&:event_name)).to eq(['some event 2', 'some event 1']) + if IS_NEW_CLICKHOUSE_SERVER + expect(Model.all.reverse_order!.to_sql).to eq('SELECT sample.* FROM sample ORDER BY sample.event_name DESC') + expect(Model.all.reverse_order!.map(&:event_name)).to eq(['some event 2', 'some event 1']) + else + expect(Model.all.reverse_order!.to_sql).to eq('SELECT sample.* FROM sample ORDER BY sample.date DESC') + expect(Model.all.reverse_order!.map(&:event_name)).to eq(['some event 1', 'some event 2']) + end end end