Module: ActiveRecord::ConnectionAdapters::ClickHouse::Quoting

Extended by:
ActiveSupport::Concern
Included in:
ActiveRecord::ConnectionAdapters::ClickHouseAdapter
Defined in:
lib/active_record/connection_adapters/clickhouse/quoting.rb

Constant Summary collapse

COLUMN_NAME_MATCHER =

disallow_raw_sql! vets order/pluck arguments against these; the abstract matchers reject backtick-quoted names — this adapter's own quoting style — so they admit table.column exactly as MySQL's do.

/
  \A
  (
    (?:
      # `table_name`.`column_name` | function(one or no argument)
      ((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`) | \w+\((?:|\g<2>)\))
    )
    (?:(?:\s+AS)?\s+(?:\w+|`\w+`))?
  )
  (?:\s*,\s*\g<1>)*
  \z
/ix
COLUMN_NAME_WITH_ORDER_MATCHER =
/
  \A
  (
    (?:
      # `table_name`.`column_name` | function(one or no argument)
      ((?:\w+\.|`\w+`\.)?(?:\w+|`\w+`) | \w+\((?:|\g<2>)\))
    )
    (?:\s+ASC|\s+DESC)?
    (?:\s+NULLS\s+(?:FIRST|LAST))?
  )
  (?:\s*,\s*\g<1>)*
  \z
/ix
QUOTED_STRING_ESCAPES =

Control characters travel as escape sequences, not raw bytes: DDL passes through String#squish (which would collapse a raw newline inside a quoted literal) and the server echoes them back escaped anyway.

{
  "\\" => "\\\\", "'" => "\\'",
  "\n" => "\\n", "\r" => "\\r", "\t" => "\\t", "\0" => "\\0"
}.freeze

Instance Method Summary collapse

Instance Method Details

#quote(value) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/active_record/connection_adapters/clickhouse/quoting.rb', line 81

def quote(value)
  case value
  when Array then "[#{value.map { |item| quote(item) }.join(", ")}]"
  when Hash then "{#{value.map { |key, item| "#{quote(key)}: #{quote(item)}" }.join(", ")}}"
  when IPAddr then "'#{quote_string(value.to_s)}'"
  else super
  end
end

#quote_string(string) ⇒ Object



63
64
65
# File 'lib/active_record/connection_adapters/clickhouse/quoting.rb', line 63

def quote_string(string)
  string.gsub(/[\\'\n\r\t\0]/, QUOTED_STRING_ESCAPES)
end

#quoted_date(value) ⇒ Object

DateTime64 stores an epoch and the server parses naive strings in its own timezone (UTC here); params reject offsets outright (code 457, PLAN.md §2). UTC is therefore the only faithful wire encoding, whatever default_timezone says.



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

def quoted_date(value)
  value = value.getutc if value.acts_like?(:time) && !value.utc?
  result = value.to_fs(:db)
  value.respond_to?(:usec) && value.usec.positive? ? "#{result}.#{format("%06d", value.usec)}" : result
end

#quoted_falseObject



77
# File 'lib/active_record/connection_adapters/clickhouse/quoting.rb', line 77

def quoted_false = "false"

#quoted_trueObject



76
# File 'lib/active_record/connection_adapters/clickhouse/quoting.rb', line 76

def quoted_true = "true"

#unquoted_falseObject



79
# File 'lib/active_record/connection_adapters/clickhouse/quoting.rb', line 79

def unquoted_false = false

#unquoted_trueObject



78
# File 'lib/active_record/connection_adapters/clickhouse/quoting.rb', line 78

def unquoted_true = true