pg_saurus 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.markdown +13 -0
- data/lib/core_ext/active_record/connection_adapters/abstract/schema_statements.rb +34 -10
- data/lib/core_ext/active_record/connection_adapters/postgresql_adapter.rb +30 -3
- data/lib/core_ext/active_record/schema_dumper.rb +7 -1
- data/lib/pg_saurus/connection_adapters/index_definition.rb +1 -1
- data/lib/pg_saurus/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfdd2685401333873ea9a135aae494ceadae569c
|
4
|
+
data.tar.gz: f9655837b68a589bf27decdf20c2f4601bd71536
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56a742d9ee24d6c27e5057aa87a9fb9034670e0e577a8ef66128850a489321019d0e5016ad0160f54a2e01dc3c8be66f992dc692d94e6d8c0f8734c6be250ed5
|
7
|
+
data.tar.gz: 4c047507f0762b571c64aec2a85a000d779bab42f98aed65652fe2e918f5f25291ea5cf62f0aa3a918d04cf5557958432281cfdae8e477247bf15f3dc97f3eea
|
data/README.markdown
CHANGED
@@ -11,6 +11,7 @@ An ActiveRecord extension to get more from PostgreSQL:
|
|
11
11
|
* [Enhancements to the Rails 4.2 foreign key support](#foreign-keys).
|
12
12
|
* Use [partial indexes](#partial-indexes).
|
13
13
|
* Use [indexes on expressions](#indexes-on-expressions).
|
14
|
+
* Use [indexes with custom ops classes](#indexes-with-operator-classes).
|
14
15
|
* [Run index creation concurrently](#concurrent-index-creation).
|
15
16
|
* Create/drop [views](#views).
|
16
17
|
* Create/drop [functions](#functions).
|
@@ -241,6 +242,18 @@ create_extension 'fuzzystrmatch'
|
|
241
242
|
add_index(:comments, 'dmetaphone(author)', using: 'gist')
|
242
243
|
```
|
243
244
|
|
245
|
+
## Indexes with operator classes
|
246
|
+
|
247
|
+
Specifying an [operator class on each column of an index](https://www.postgresql.org/docs/10/indexes-opclass.html) is supported.
|
248
|
+
|
249
|
+
### Examples
|
250
|
+
|
251
|
+
Add an index with a custom ops class:
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
add_index(:books, "title varchar_pattern_ops")
|
255
|
+
```
|
256
|
+
|
244
257
|
## Concurrent index creation
|
245
258
|
|
246
259
|
PostgreSQL supports concurrent index creation. PgSaurus supports that feature by adding support
|
@@ -5,6 +5,8 @@ module ActiveRecord
|
|
5
5
|
# function call
|
6
6
|
FUNCTIONAL_INDEX_REGEXP = /(\w+)\(((?:'.+'(?:::\w+)?, *)*)(\w+)\)/
|
7
7
|
|
8
|
+
# Regexp used to find the operator name
|
9
|
+
OPERATOR_REGEXP = /(.+)\s(\w+)$/
|
8
10
|
|
9
11
|
# Redefine original add_index method to handle :concurrently option.
|
10
12
|
#
|
@@ -132,24 +134,46 @@ module ActiveRecord
|
|
132
134
|
# Override super method to provide support for expression column names.
|
133
135
|
def quoted_columns_for_index(column_names, options = {})
|
134
136
|
column_names.map do |name|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
137
|
+
column_name, operator_name = split_column_name(name)
|
138
|
+
|
139
|
+
result_name = if column_name =~ FUNCTIONAL_INDEX_REGEXP
|
140
|
+
"#{$1}(#{$2}#{quote_column_name($3)})"
|
141
|
+
else
|
142
|
+
quote_column_name(column_name)
|
143
|
+
end
|
144
|
+
|
145
|
+
result_name += " " + operator_name if operator_name
|
146
|
+
|
147
|
+
result_name
|
140
148
|
end
|
141
149
|
end
|
142
150
|
protected :quoted_columns_for_index
|
143
151
|
|
144
152
|
# Map an expression to a name appropriate for an index.
|
145
|
-
def expression_index_name(
|
146
|
-
|
147
|
-
|
153
|
+
def expression_index_name(name)
|
154
|
+
column_name, operator_name = split_column_name(name)
|
155
|
+
|
156
|
+
result_name = if column_name =~ FUNCTIONAL_INDEX_REGEXP
|
157
|
+
"#{$1.downcase}_#{$3}"
|
158
|
+
else
|
159
|
+
column_name
|
160
|
+
end
|
161
|
+
|
162
|
+
result_name += "_" + operator_name if operator_name
|
163
|
+
|
164
|
+
result_name
|
165
|
+
end
|
166
|
+
private :expression_index_name
|
167
|
+
|
168
|
+
# Split column name to name and operator class if possible.
|
169
|
+
def split_column_name(name)
|
170
|
+
if name =~ OPERATOR_REGEXP
|
171
|
+
return $1, $2
|
148
172
|
else
|
149
|
-
|
173
|
+
return name, nil
|
150
174
|
end
|
151
175
|
end
|
152
|
-
private :
|
176
|
+
private :split_column_name
|
153
177
|
end
|
154
178
|
end
|
155
179
|
end
|
@@ -71,7 +71,7 @@ module ActiveRecord # :nodoc:
|
|
71
71
|
schemas = schema ? "ARRAY['#{schema}']" : 'current_schemas(false)'
|
72
72
|
|
73
73
|
result = query(<<-SQL, name)
|
74
|
-
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid, am.amname
|
74
|
+
SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid, am.amname, d.indclass
|
75
75
|
FROM pg_class t
|
76
76
|
INNER JOIN pg_index d ON t.oid = d.indrelid
|
77
77
|
INNER JOIN pg_class i ON d.indexrelid = i.oid
|
@@ -90,11 +90,14 @@ module ActiveRecord # :nodoc:
|
|
90
90
|
:keys => row[2].split(" "),
|
91
91
|
:definition => row[3],
|
92
92
|
:id => row[4],
|
93
|
-
:access_method => row[5]
|
93
|
+
:access_method => row[5],
|
94
|
+
:operators => row[6].split(" ")
|
94
95
|
}
|
95
96
|
|
96
97
|
column_names = find_column_names(table_name, index)
|
97
98
|
|
99
|
+
operator_names = find_operator_names(column_names, index)
|
100
|
+
|
98
101
|
unless column_names.empty?
|
99
102
|
where = find_where_statement(index)
|
100
103
|
lengths = find_lengths(index)
|
@@ -106,7 +109,8 @@ module ActiveRecord # :nodoc:
|
|
106
109
|
column_names,
|
107
110
|
lengths,
|
108
111
|
where,
|
109
|
-
index[:access_method]
|
112
|
+
index[:access_method],
|
113
|
+
operator_names
|
110
114
|
)
|
111
115
|
end
|
112
116
|
end.compact
|
@@ -141,6 +145,29 @@ module ActiveRecord # :nodoc:
|
|
141
145
|
column_names
|
142
146
|
end
|
143
147
|
|
148
|
+
# Find non-default operator class names for columns from index.
|
149
|
+
#
|
150
|
+
# @param column_names [Array] List of columns from index.
|
151
|
+
# @param index [Hash] index index attributes
|
152
|
+
# @return [Hash]
|
153
|
+
def find_operator_names(column_names, index)
|
154
|
+
column_names.each_with_index.inject({}) do |class_names, (column_name, column_index)|
|
155
|
+
result = query(<<-SQL, "Classes for columns for index #{index[:name]} for column #{column_name}")
|
156
|
+
SELECT op.opcname, op.opcdefault
|
157
|
+
FROM pg_opclass op
|
158
|
+
WHERE op.oid = #{index[:operators][column_index]};
|
159
|
+
SQL
|
160
|
+
|
161
|
+
row = result.first
|
162
|
+
|
163
|
+
if row && row[1] == "f"
|
164
|
+
class_names[column_name] = row[0]
|
165
|
+
end
|
166
|
+
|
167
|
+
class_names
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
144
171
|
# Splits only on commas outside of parens
|
145
172
|
def split_expression(expression)
|
146
173
|
result = []
|
@@ -15,9 +15,15 @@ module ActiveRecord #:nodoc:
|
|
15
15
|
def indexes(table, stream)
|
16
16
|
if (indexes = @connection.indexes(table)).any?
|
17
17
|
add_index_statements = indexes.map do |index|
|
18
|
+
columns = index.columns.map do |column_name|
|
19
|
+
column_name += ' ' +index.operators[column_name] if index.operators.key?(column_name)
|
20
|
+
|
21
|
+
column_name
|
22
|
+
end
|
23
|
+
|
18
24
|
statement_parts = [
|
19
25
|
('add_index ' + index.table.inspect),
|
20
|
-
|
26
|
+
columns.inspect,
|
21
27
|
(':name => ' + index.name.inspect),
|
22
28
|
]
|
23
29
|
statement_parts << ':unique => true' if index.unique
|
@@ -3,6 +3,6 @@ module PgSaurus::ConnectionAdapters
|
|
3
3
|
# Overrides ActiveRecord::ConnectionAdapters::IndexDefinition
|
4
4
|
# with the additional :where parameter.
|
5
5
|
class IndexDefinition < Struct.new( :table, :name, :unique, :columns,
|
6
|
-
:lengths, :where, :access_method )
|
6
|
+
:lengths, :where, :access_method, :operators )
|
7
7
|
end
|
8
8
|
end
|
data/lib/pg_saurus/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_saurus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Potapov Sergey
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date:
|
16
|
+
date: 2019-03-14 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: pg
|