Skip to content

Commit

Permalink
Support codec column #135, refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
PNixx committed Oct 23, 2024
1 parent a59294e commit 1edbaa5
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 19 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
ruby-version: ${{ matrix.version.ruby }}
bundler-cache: true

- run: bundle exec rspec spec/single
- run: bundle exec rspec spec/single --format progress

tests_cluster:
name: Testing cluster server
Expand Down Expand Up @@ -94,4 +94,4 @@ jobs:
ruby-version: ${{ matrix.version.ruby }}
bundler-cache: true

- run: bundle exec rspec spec/cluster
- run: bundle exec rspec spec/cluster --format progress
21 changes: 21 additions & 0 deletions lib/active_record/connection_adapters/clickhouse/column.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module ActiveRecord
module ConnectionAdapters
module Clickhouse
class Column < ActiveRecord::ConnectionAdapters::Column

attr_reader :codec

def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, codec: nil, **args)
super
@codec = codec
end

private

def deduplicated
self
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def add_column_options!(sql, options)
if options[:map] == true
sql.gsub!(/\s+(.*)/, ' Map(String, \1)')
end
if options[:codec]
sql.gsub!(/\s+(.*)/, " \\1 CODEC(#{options[:codec]})")
end
sql.gsub!(/(\sString)\(\d+\)/, '\1')
sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
sql
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Clickhouse
module SchemaStatements
DEFAULT_RESPONSE_FORMAT = 'JSONCompactEachRowWithNamesAndTypes'.freeze

DB_EXCEPTION_REGEXP = /\ACode: \d.+\. DB::Exception:/.freeze
DB_EXCEPTION_REGEXP = /\ACode:\s+\d+\.\s+DB::Exception:/.freeze

def execute(sql, name = nil, settings: {})
do_execute(sql, name, settings: settings)
Expand Down Expand Up @@ -225,7 +225,7 @@ def new_column_from_field(table_name, field, _definitions)
default_value = extract_value_from_default(field[3], field[2])
default_function = extract_default_function(field[3])
default_value = lookup_cast_type(sql_type).cast(default_value)
ClickhouseColumn.new(field[0], default_value, type_metadata, field[1].include?('Nullable'), default_function)
Clickhouse::Column.new(field[0], default_value, type_metadata, field[1].include?('Nullable'), default_function, codec: field[5].presence)
end

protected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,15 @@ def enum(*args, **options)
args.each { |name| column(name, kind, **options.except(:limit)) }
end

def column(name, type, index: nil, **options)
options[:null] = false if type.match?(/Nullable\([^)]+\)/)
super(name, type, index: index, **options)
end

private

def valid_column_definition_options
super + [:array, :low_cardinality, :fixed_string, :value, :type, :map]
super + [:array, :low_cardinality, :fixed_string, :value, :type, :map, :codec]
end
end

Expand Down
10 changes: 2 additions & 8 deletions lib/active_record/connection_adapters/clickhouse_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
require 'active_record/connection_adapters/clickhouse/oid/big_integer'
require 'active_record/connection_adapters/clickhouse/oid/map'
require 'active_record/connection_adapters/clickhouse/oid/uuid'
require 'active_record/connection_adapters/clickhouse/column'
require 'active_record/connection_adapters/clickhouse/quoting'
require 'active_record/connection_adapters/clickhouse/schema_definitions'
require 'active_record/connection_adapters/clickhouse/schema_creation'
require 'active_record/connection_adapters/clickhouse/schema_statements'
require 'active_record/connection_adapters/clickhouse/table_definition'
require 'net/http'
require 'openssl'

Expand Down Expand Up @@ -77,13 +78,6 @@ module ConnectionAdapters
register "clickhouse", "ActiveRecord::ConnectionAdapters::ClickhouseAdapter", "active_record/connection_adapters/clickhouse_adapter"
end

class ClickhouseColumn < Column
private
def deduplicated
self
end
end

class ClickhouseAdapter < AbstractAdapter
include Clickhouse::Quoting

Expand Down
12 changes: 7 additions & 5 deletions lib/clickhouse-activerecord/schema_dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def table(table, stream)
# super(table.gsub(/^\.inner\./, ''), stream)

# detect view table
view_match = sql.match(/^CREATE\s+(MATERIALIZED\s+)?VIEW\s+\S+\s+(TO (\S+))?/)
view_match = sql.match(/^CREATE\s+(MATERIALIZED\s+)?VIEW\s+\S+\s+(?:TO (\S+))?/)
end

# Copy from original dumper
Expand All @@ -52,7 +52,7 @@ def table(table, stream)
# Add materialize flag
tbl.print ', view: true' if view_match
tbl.print ', materialized: true' if view_match && view_match[1].presence
tbl.print ", to: \"#{view_match[3]}\"" if view_match && view_match[3].presence
tbl.print ", to: \"#{view_match[2]}\"" if view_match && view_match[2].presence
end

if (id = columns.detect { |c| c.name == 'id' })
Expand Down Expand Up @@ -145,21 +145,22 @@ def schema_unsigned(column)
end

def schema_array(column)
(column.sql_type =~ /Array?\(/).nil? ? nil : true
(column.sql_type =~ /Array\(/).nil? ? nil : true
end

def schema_map(column)
if column.sql_type =~ /Map\(([^,]+),\s*(Array)\)/
return :array
end

(column.sql_type =~ /Map?\(/).nil? ? nil : true
(column.sql_type =~ /Map\(/).nil? ? nil : true
end

def schema_low_cardinality(column)
(column.sql_type =~ /LowCardinality?\(/).nil? ? nil : true
(column.sql_type =~ /LowCardinality\(/).nil? ? nil : true
end

# @param [ActiveRecord::ConnectionAdapters::Clickhouse::Column] column
def prepare_column_options(column)
spec = {}
spec[:unsigned] = schema_unsigned(column)
Expand All @@ -169,6 +170,7 @@ def prepare_column_options(column)
spec[:array] = nil
end
spec[:low_cardinality] = schema_low_cardinality(column)
spec[:codec] = column.codec.inspect if column.codec
spec.merge(super).compact
end

Expand Down
2 changes: 1 addition & 1 deletion lib/clickhouse-activerecord/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ClickhouseActiverecord
VERSION = '1.1.3'
VERSION = '1.2.0'
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

class CreateSomeTable < ActiveRecord::Migration[7.1]
def up
create_table :some, id: false, force: true do |t|
t.column :custom, "Nullable(UInt64) CODEC(T64, LZ4)"
end
end
end

14 changes: 14 additions & 0 deletions spec/single/migration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,20 @@
end
end

context 'codec' do
let(:directory) { 'dsl_table_with_codec' }
it 'creates a table with custom column' do
subject

current_schema = schema(model)

expect(current_schema.keys.count).to eq(1)
expect(current_schema).to have_key('custom')
expect(current_schema['custom'].sql_type).to eq('Nullable(UInt64)')
expect(current_schema['custom'].codec).to eq('T64, LZ4')
end
end

context 'datetime' do
let(:directory) { 'dsl_table_with_datetime_creation' }
it 'creates a table with datetime columns' do
Expand Down
5 changes: 5 additions & 0 deletions spec/single/model_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ class ModelPk < ActiveRecord::Base
end
end

it 'DB::Exception in row value' do
Model.create!(event_name: 'DB::Exception')
expect(Model.first.event_name).to eq('DB::Exception')
end

describe '#do_execute' do
it 'returns formatted result' do
result = Model.connection.do_execute('SELECT 1 AS t')
Expand Down

0 comments on commit 1edbaa5

Please sign in to comment.