Module: ActiveRecord::ConnectionAdapters::Clickhouse::SchemaStatements

Included in:
ActiveRecord::ConnectionAdapters::ClickhouseAdapter
Defined in:
lib/active_record/connection_adapters/clickhouse/schema_statements.rb

Constant Summary collapse

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

Instance Method Summary collapse

Instance Method Details

#add_index_options(table_name, expression, **options) ⇒ Object



101
102
103
104
105
106
107
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 101

def add_index_options(table_name, expression, **options)
  options.assert_valid_keys(:name, :type, :granularity, :first, :after, :if_not_exists, :if_exists)

  validate_index_length!(table_name, options[:name])

  IndexDefinition.new(table_name, options[:name], expression, options[:type], options[:granularity], first: options[:first], after: options[:after], if_not_exists: options[:if_not_exists], if_exists: options[:if_exists])
end

#assume_migrated_upto_version(version, migrations_paths = nil) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 141

def assume_migrated_upto_version(version, migrations_paths = nil)
  version = version.to_i
  sm_table = quote_table_name(schema_migration.table_name)

  migrated = migration_context.get_all_versions
  versions = migration_context.migrations.map(&:version)

  unless migrated.include?(version)
    exec_insert "INSERT INTO #{sm_table} (version) VALUES (#{quote(version.to_s)})", nil, nil
  end

  inserting = (versions - migrated).select { |v| v < version }
  if inserting.any?
    if (duplicate = inserting.detect { |v| inserting.count(v) > 1 })
      raise "Duplicate migration #{duplicate}. Please renumber your migrations to resolve the conflict."
    end
    do_execute(insert_versions_sql(inserting), nil, format: nil, settings: {max_partitions_per_insert_block: [100, inserting.size].max})
  end
end

#data_sourcesObject



109
110
111
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 109

def data_sources
  tables
end

#do_execute(sql, name = nil, format: DEFAULT_RESPONSE_FORMAT, settings: {}) ⇒ Object



120
121
122
123
124
125
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 120

def do_execute(sql, name = nil, format: DEFAULT_RESPONSE_FORMAT, settings: {})
  log(sql, "#{adapter_name} #{name}") do
    res = request(sql, format, settings)
    process_response(res, format, sql)
  end
end

#do_system_execute(sql, name = nil) ⇒ Object



113
114
115
116
117
118
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 113

def do_system_execute(sql, name = nil)
  log_with_debug(sql, "#{adapter_name} #{name}") do
    res = request(sql, DEFAULT_RESPONSE_FORMAT)
    process_response(res, DEFAULT_RESPONSE_FORMAT, sql)
  end
end

#exec_delete(_sql, _name = nil, _binds = []) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 51

def exec_delete(_sql, _name = nil, _binds = [])
  log(_sql, "#{adapter_name} #{_name}") do
    res = request(_sql)
    begin
      data = JSON.parse(res.header['x-clickhouse-summary'])
      data['result_rows'].to_i
    rescue JSONError
      0
    end
  end
end

#exec_insert(sql, name, _binds, _pk = nil, _sequence_name = nil, returning: nil) ⇒ Object



17
18
19
20
21
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 17

def exec_insert(sql, name, _binds, _pk = nil, _sequence_name = nil, returning: nil)
  new_sql = sql.dup.sub(/ (DEFAULT )?VALUES/, " VALUES")
  do_execute(new_sql, name, format: nil)
  true
end

#exec_insert_all(sql, name) ⇒ Object



39
40
41
42
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 39

def exec_insert_all(sql, name)
  do_execute(sql, name, format: nil)
  true
end

#exec_update(_sql, _name = nil, _binds = []) ⇒ Object



45
46
47
48
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 45

def exec_update(_sql, _name = nil, _binds = [])
  do_execute(_sql, _name, format: nil)
  0
end

#execute(sql, name = nil, settings: {}) ⇒ Object



13
14
15
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 13

def execute(sql, name = nil, settings: {})
  do_execute(sql, name, settings: settings)
end

#functionsObject



81
82
83
84
85
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 81

def functions
  result = do_system_execute("SELECT name FROM system.functions WHERE origin = 'SQLUserDefined' ORDER BY name")
  return [] if result.nil?
  result['data'].flatten
end

#indexes(table_name, name = nil) ⇒ Object

Not indexes on clickhouse



97
98
99
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 97

def indexes(table_name, name = nil)
  []
end

#internal_exec_query(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 23

def internal_exec_query(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false)
  result = do_execute(sql, name)
  columns = result['meta'].map { |m| m['name'] }
  types = {}
  result['meta'].each_with_index do |m, i|
    # need use column name and index after commit in 7.2:
    # https://github.com/rails/rails/commit/24dbf7637b1d5cd6eb3d7100b8d0f6872c3fee3c
    types[m['name']] = types[i] = type_map.lookup(m['type'])
  end
  ActiveRecord::Result.new(columns, result['data'], types)
rescue ActiveRecord::ActiveRecordError => e
  raise e
rescue StandardError => e
  raise ActiveRecord::ActiveRecordError, "Response: #{e.message}"
end

#internal_metadataObject



136
137
138
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 136

def 
  pool.
end

#materialized_views(name = nil) ⇒ Object



75
76
77
78
79
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 75

def materialized_views(name = nil)
  result = do_system_execute("SHOW TABLES WHERE engine = 'MaterializedView'", name)
  return [] if result.nil?
  result['data'].flatten
end

#migration_contextObject



132
133
134
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 132

def migration_context
  pool.migration_context
end

#schema_migrationObject



128
129
130
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 128

def schema_migration
  pool.schema_migration
end

#show_create_function(function) ⇒ Object



87
88
89
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 87

def show_create_function(function)
  do_execute("SELECT create_query FROM system.functions WHERE origin = 'SQLUserDefined' AND name = '#{function}'", format: nil)
end

#table_options(table) ⇒ Object



91
92
93
94
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 91

def table_options(table)
  sql = show_create_table(table)
  { options: sql.gsub(/^(?:.*?)(?:ENGINE = (.*?))?( AS SELECT .*?)?$/, '\\1').presence, as: sql.match(/^CREATE (?:.*?) AS (SELECT .*?)$/).try(:[], 1) }.compact
end

#tables(name = nil) ⇒ Object



63
64
65
66
67
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 63

def tables(name = nil)
  result = do_system_execute("SHOW TABLES WHERE name NOT LIKE '.inner_id.%'", name)
  return [] if result.nil?
  result['data'].flatten
end

#views(name = nil) ⇒ Object



69
70
71
72
73
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 69

def views(name = nil)
  result = do_system_execute("SHOW TABLES WHERE engine = 'View'", name)
  return [] if result.nil?
  result['data'].flatten
end

#with_yaml_fallback(value) ⇒ Object



163
164
165
166
167
168
169
# File 'lib/active_record/connection_adapters/clickhouse/schema_statements.rb', line 163

def with_yaml_fallback(value) # :nodoc:
  if value.is_a?(Array) || value.is_a?(Hash)
    value
  else
    super
  end
end