1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# frozen_string_literal: true
module Gitlab
module Database
module Partitioning
class SingleNumericListPartition
include Comparable
def self.from_sql(table, partition_name, definition)
# A list partition can support multiple values, but we only support a single number
matches = definition.match(/FOR VALUES IN \('(?<value>\d+)'\)/)
raise ArgumentError, 'Unknown partition definition' unless matches
value = Integer(matches[:value])
new(table, value, partition_name: partition_name)
end
attr_reader :table, :value
def initialize(table, value, partition_name: nil )
@table = table
@value = value
@partition_name = partition_name
end
def partition_name
@partition_name || "#{table}_#{value}"
end
def to_sql
<<~SQL
CREATE TABLE IF NOT EXISTS #{fully_qualified_partition}
PARTITION OF #{conn.quote_table_name(table)}
FOR VALUES IN (#{conn.quote(value)})
SQL
end
def to_detach_sql
<<~SQL
ALTER TABLE #{conn.quote_table_name(table)}
DETACH PARTITION #{fully_qualified_partition}
SQL
end
def ==(other)
table == other.table &&
partition_name == other.partition_name &&
value == other.value
end
alias_method :eql?, :==
def hash
[table, partition_name, value].hash
end
def <=>(other)
return if table != other.table
value <=> other.value
end
private
def fully_qualified_partition
"%s.%s" % [conn.quote_table_name(Gitlab::Database::DYNAMIC_PARTITIONS_SCHEMA), conn.quote_table_name(partition_name)]
end
def conn
@conn ||= Gitlab::Database::SharedModel.connection
end
end
end
end
end
|