pgslice 0.4.5 → 0.4.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -25
- data/LICENSE.txt +1 -1
- data/README.md +80 -17
- data/exe/pgslice +4 -5
- data/lib/pgslice/cli/add_partitions.rb +5 -2
- data/lib/pgslice/cli/swap.rb +1 -1
- data/lib/pgslice/cli/unswap.rb +1 -1
- data/lib/pgslice/cli.rb +1 -1
- data/lib/pgslice/helpers.rb +6 -2
- data/lib/pgslice/table.rb +20 -11
- data/lib/pgslice/version.rb +1 -1
- data/lib/pgslice.rb +3 -1
- metadata +8 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d3a279841af6ee62759c9570149cda73460c674c383aef78d7b99fa5c9840ec
|
4
|
+
data.tar.gz: 48462eb02783c097d0553071880e75650263d662cf755e8fa977b1d4e25ccc0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c95fe04d9c90f524c9cd778f5a5e05013ff4655982cd4ed1420a024c5c17a97d3de679c86e1d66800a9ee3ab7e29eec8abec8676041d7e07d7ebce96052315f
|
7
|
+
data.tar.gz: 5d43e4d5dc94f29538abd25bd2e3676dc47e1b5cdce646e345539d7543f4b21fb2d9d33ecb08c69df81283150643ad423817179719f712d963b0aba791c10d89
|
data/CHANGELOG.md
CHANGED
@@ -1,122 +1,137 @@
|
|
1
|
-
## 0.4.
|
1
|
+
## 0.4.8 (2022-02-28)
|
2
|
+
|
3
|
+
- Fixed error with pg 1.3
|
4
|
+
- Reduced size of Docker image
|
5
|
+
|
6
|
+
## 0.4.7 (2020-08-14)
|
7
|
+
|
8
|
+
- Added `--tablespace` option to `add_partitions`
|
9
|
+
- Fixed sequence query if sequence in different schema than table
|
10
|
+
|
11
|
+
## 0.4.6 (2020-05-29)
|
12
|
+
|
13
|
+
- Ensure correct order with multi-column primary keys
|
14
|
+
- Ensure fill always uses correct date range (bug introduced in 0.4.5)
|
15
|
+
|
16
|
+
## 0.4.5 (2018-10-18)
|
2
17
|
|
3
18
|
- Added support for Postgres 11 foreign key improvements
|
4
19
|
- Improved versioning
|
5
20
|
|
6
|
-
## 0.4.4
|
21
|
+
## 0.4.4 (2018-08-18)
|
7
22
|
|
8
23
|
- Added partitioning by `year`
|
9
24
|
- Fixed `--source-table` and `--dest-table` options
|
10
25
|
- Added descriptions to options
|
11
26
|
|
12
|
-
## 0.4.3
|
27
|
+
## 0.4.3 (2018-08-16)
|
13
28
|
|
14
29
|
- Fixed sequence ownership
|
15
30
|
- Improved help
|
16
31
|
|
17
|
-
## 0.4.2
|
32
|
+
## 0.4.2 (2018-07-23)
|
18
33
|
|
19
34
|
- Added support for Postgres 11 index improvements
|
20
35
|
- Added support for all connection options
|
21
36
|
|
22
|
-
## 0.4.1
|
37
|
+
## 0.4.1 (2018-04-30)
|
23
38
|
|
24
39
|
- Better support for schemas
|
25
40
|
- Use latest partition for schema
|
26
41
|
- Added support for composite primary keys
|
27
42
|
|
28
|
-
## 0.4.0
|
43
|
+
## 0.4.0 (2017-10-07)
|
29
44
|
|
30
45
|
- Added support for declarative partitioning
|
31
46
|
- Added support for foreign keys
|
32
47
|
|
33
|
-
## 0.3.6
|
48
|
+
## 0.3.6 (2017-07-10)
|
34
49
|
|
35
50
|
- Fixed drop trigger on `unprep` for non-lowercase tables
|
36
51
|
- Fixed index creation for non-lowercase tables
|
37
52
|
|
38
|
-
## 0.3.5
|
53
|
+
## 0.3.5 (2017-07-06)
|
39
54
|
|
40
55
|
- Added support for non-lowercase tables and columns
|
41
56
|
|
42
|
-
## 0.3.4
|
57
|
+
## 0.3.4 (2017-07-06)
|
43
58
|
|
44
59
|
- Added `analyze` method
|
45
60
|
- Fixed `fill` with `--dry-run` option
|
46
61
|
- Better error message for tables without primary key
|
47
62
|
|
48
|
-
## 0.3.3
|
63
|
+
## 0.3.3 (2017-03-22)
|
49
64
|
|
50
65
|
- Fixed error when creating partitions
|
51
66
|
|
52
|
-
## 0.3.2
|
67
|
+
## 0.3.2 (2016-12-15)
|
53
68
|
|
54
69
|
- Exit with error code on interrupt
|
55
70
|
- Fixed `--start` option with `--swapped`
|
56
71
|
|
57
|
-
## 0.3.1
|
72
|
+
## 0.3.1 (2016-12-13)
|
58
73
|
|
59
74
|
- Fixed exception with `--no-partition` option
|
60
75
|
- Use proper cast type in `fill` method for legacy `timestamptz` columns
|
61
76
|
|
62
|
-
## 0.3.0
|
77
|
+
## 0.3.0 (2016-12-12)
|
63
78
|
|
64
79
|
- Better query performance for `timestamptz` columns
|
65
80
|
- Added support for schemas other than `public`
|
66
81
|
|
67
|
-
## 0.2.3
|
82
|
+
## 0.2.3 (2016-10-10)
|
68
83
|
|
69
84
|
- Added `--dest-table` option to `fill`
|
70
85
|
- Fixed errors with `fill` when no partitions created
|
71
86
|
|
72
|
-
## 0.2.2
|
87
|
+
## 0.2.2 (2016-10-06)
|
73
88
|
|
74
89
|
- Set `lock_timeout` on `swap` to prevent bad things from happening
|
75
90
|
- Friendlier error messages
|
76
91
|
|
77
|
-
## 0.2.1
|
92
|
+
## 0.2.1 (2016-09-28)
|
78
93
|
|
79
94
|
- Added `--where` option to `fill`
|
80
95
|
- Fixed partition detection with `fill`
|
81
96
|
- Fixed error for columns named `user` with `fill`
|
82
97
|
|
83
|
-
## 0.2.0
|
98
|
+
## 0.2.0 (2016-09-22)
|
84
99
|
|
85
100
|
- Switched to new trigger, which is about 20% faster
|
86
101
|
|
87
|
-
## 0.1.7
|
102
|
+
## 0.1.7 (2016-09-14)
|
88
103
|
|
89
104
|
- Added `--source-table` option to `fill`
|
90
105
|
|
91
|
-
## 0.1.6
|
106
|
+
## 0.1.6 (2016-08-04)
|
92
107
|
|
93
108
|
- Added `--no-partition` option to `prep`
|
94
109
|
- Added `--url` option
|
95
110
|
|
96
|
-
## 0.1.5
|
111
|
+
## 0.1.5 (2016-04-26)
|
97
112
|
|
98
113
|
- Removed `activesupport` dependency for speed
|
99
114
|
- Fixed `fill` for months
|
100
115
|
|
101
|
-
## 0.1.4
|
116
|
+
## 0.1.4 (2016-04-24)
|
102
117
|
|
103
118
|
- Added sequence ownership
|
104
119
|
- Default to 0 for `--past` and `--future` options
|
105
120
|
- Better `fill` with `--swapped`
|
106
121
|
|
107
|
-
## 0.1.3
|
122
|
+
## 0.1.3 (2016-04-24)
|
108
123
|
|
109
124
|
- Fixed table inheritance
|
110
125
|
|
111
|
-
## 0.1.2
|
126
|
+
## 0.1.2 (2016-04-24)
|
112
127
|
|
113
128
|
- Added `--dry-run` option
|
114
129
|
- Print sql to stdout instead of stderr
|
115
130
|
|
116
|
-
## 0.1.1
|
131
|
+
## 0.1.1 (2016-04-24)
|
117
132
|
|
118
133
|
- Added sql commands to output
|
119
134
|
|
120
|
-
## 0.1.0
|
135
|
+
## 0.1.0 (2016-04-24)
|
121
136
|
|
122
137
|
- First release
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,7 @@ Postgres partitioning as easy as pie. Works great for both new and existing tabl
|
|
4
4
|
|
5
5
|
:tangerine: Battle-tested at [Instacart](https://www.instacart.com/opensource)
|
6
6
|
|
7
|
-
[![Build Status](https://
|
7
|
+
[![Build Status](https://github.com/ankane/pgslice/workflows/build/badge.svg?branch=master)](https://github.com/ankane/pgslice/actions)
|
8
8
|
|
9
9
|
## Install
|
10
10
|
|
@@ -14,7 +14,7 @@ pgslice is a command line tool. To install, run:
|
|
14
14
|
gem install pgslice
|
15
15
|
```
|
16
16
|
|
17
|
-
This will give you the `pgslice` command.
|
17
|
+
This will give you the `pgslice` command. You can also install it with [Homebrew](#homebrew). If installation fails, you may need to install [dependencies](#dependencies).
|
18
18
|
|
19
19
|
## Steps
|
20
20
|
|
@@ -34,16 +34,14 @@ This will give you the `pgslice` command.
|
|
34
34
|
|
35
35
|
Period can be `day`, `month`, or `year`.
|
36
36
|
|
37
|
-
This creates a table named `<table>_intermediate
|
37
|
+
This creates a partitioned table named `<table>_intermediate`.
|
38
38
|
|
39
|
-
4. Add partitions
|
39
|
+
4. Add partitions to the intermediate table
|
40
40
|
|
41
41
|
```sh
|
42
42
|
pgslice add_partitions <table> --intermediate --past 3 --future 3
|
43
43
|
```
|
44
44
|
|
45
|
-
This creates child tables that inherit from the intermediate table.
|
46
|
-
|
47
45
|
Use the `--past` and `--future` options to control the number of partitions.
|
48
46
|
|
49
47
|
5. *Optional, for tables with data* - Fill the partitions in batches with data from the original table
|
@@ -80,7 +78,7 @@ This will give you the `pgslice` command.
|
|
80
78
|
|
81
79
|
```sql
|
82
80
|
pg_dump -c -Fc -t <table>_retired $PGSLICE_URL > <table>_retired.dump
|
83
|
-
psql -c "DROP <table>_retired" $PGSLICE_URL
|
81
|
+
psql -c "DROP TABLE <table>_retired" $PGSLICE_URL
|
84
82
|
```
|
85
83
|
|
86
84
|
## Sample Output
|
@@ -173,7 +171,7 @@ ALTER TABLE "public"."visits" RENAME TO "visits_retired";
|
|
173
171
|
|
174
172
|
ALTER TABLE "public"."visits_intermediate" RENAME TO "visits";
|
175
173
|
|
176
|
-
ALTER SEQUENCE "visits_id_seq" OWNED BY "public"."visits"."id";
|
174
|
+
ALTER SEQUENCE "public"."visits_id_seq" OWNED BY "public"."visits"."id";
|
177
175
|
|
178
176
|
COMMIT;
|
179
177
|
```
|
@@ -220,7 +218,7 @@ Back up and drop older partitions each day, month, or year.
|
|
220
218
|
|
221
219
|
```sh
|
222
220
|
pg_dump -c -Fc -t <table>_201809 $PGSLICE_URL > <table>_201809.dump
|
223
|
-
psql -c "DROP <table>_201809" $PGSLICE_URL
|
221
|
+
psql -c "DROP TABLE <table>_201809" $PGSLICE_URL
|
224
222
|
```
|
225
223
|
|
226
224
|
If you use [Amazon S3](https://aws.amazon.com/s3/) for backups, [s3cmd](https://github.com/s3tools/s3cmd) is a nice tool.
|
@@ -229,6 +227,15 @@ If you use [Amazon S3](https://aws.amazon.com/s3/) for backups, [s3cmd](https://
|
|
229
227
|
s3cmd put <table>_201809.dump s3://<s3-bucket>/<table>_201809.dump
|
230
228
|
```
|
231
229
|
|
230
|
+
## Schema Updates
|
231
|
+
|
232
|
+
Once a table is partitioned, make schema updates on the master table only (not partitions). This includes adding, removing, and modifying columns, as well as adding and removing indexes and foreign keys.
|
233
|
+
|
234
|
+
A few exceptions are:
|
235
|
+
|
236
|
+
- For Postgres 10, make index and foreign key updates on partitions only
|
237
|
+
- For Postgres < 10, make index and foreign key updates on the master table and all partitions
|
238
|
+
|
232
239
|
## Additional Commands
|
233
240
|
|
234
241
|
To undo prep (which will delete partitions), use:
|
@@ -243,6 +250,14 @@ To undo swap, use:
|
|
243
250
|
pgslice unswap <table>
|
244
251
|
```
|
245
252
|
|
253
|
+
## Additional Options
|
254
|
+
|
255
|
+
Set the tablespace when adding partitions
|
256
|
+
|
257
|
+
```sh
|
258
|
+
pgslice add_partitions <table> --tablespace fastspace
|
259
|
+
```
|
260
|
+
|
246
261
|
## App Considerations
|
247
262
|
|
248
263
|
This set up allows you to read and write with the original table name with no knowledge it’s partitioned. However, there are a few things to be aware of.
|
@@ -273,6 +288,32 @@ Before Postgres 10, if you use `INSERT` statements with a `RETURNING` clause (as
|
|
273
288
|
1. Insert directly into the partition
|
274
289
|
2. Get value before the insert with `SELECT nextval('sequence_name')` (for multiple rows, append `FROM generate_series(1, n)`)
|
275
290
|
|
291
|
+
## Frameworks
|
292
|
+
|
293
|
+
### Rails
|
294
|
+
|
295
|
+
For Postgres 10+, specify the primary key for partitioned models to ensure it’s returned.
|
296
|
+
|
297
|
+
```ruby
|
298
|
+
class Visit < ApplicationRecord
|
299
|
+
self.primary_key = "id"
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
303
|
+
Before Postgres 10, preload the value.
|
304
|
+
|
305
|
+
```ruby
|
306
|
+
class Visit < ApplicationRecord
|
307
|
+
before_create do
|
308
|
+
self.id ||= self.class.connection.select_all("SELECT nextval('#{self.class.sequence_name}')").first["nextval"]
|
309
|
+
end
|
310
|
+
end
|
311
|
+
```
|
312
|
+
|
313
|
+
### Other Frameworks
|
314
|
+
|
315
|
+
Please submit a PR if additional configuration is needed.
|
316
|
+
|
276
317
|
## One Off Tasks
|
277
318
|
|
278
319
|
You can also use pgslice to reduce the size of a table without partitioning by creating a new table, filling it with a subset of records, and swapping it in.
|
@@ -283,12 +324,9 @@ pgslice fill <table> --where "id > 1000" # use any conditions
|
|
283
324
|
pgslice swap <table>
|
284
325
|
```
|
285
326
|
|
286
|
-
##
|
327
|
+
## Triggers
|
287
328
|
|
288
|
-
|
289
|
-
|
290
|
-
- To add, remove, or modify a column, make the update on the master table only.
|
291
|
-
- To add or remove an index or foreign key, make the update on the master table. For Postgres < 11, make the update on all partitions as well.
|
329
|
+
Triggers aren’t copied from the original table. You can set up triggers on the intermediate table if needed. Note that Postgres doesn’t support `BEFORE / FOR EACH ROW` triggers on partitioned tables.
|
292
330
|
|
293
331
|
## Declarative Partitioning
|
294
332
|
|
@@ -296,7 +334,31 @@ Postgres 10 introduces [declarative partitioning](https://www.postgresql.org/doc
|
|
296
334
|
|
297
335
|
## Data Protection
|
298
336
|
|
299
|
-
Always make sure your connection is secure when connecting to
|
337
|
+
Always make sure your [connection is secure](https://ankane.org/postgres-sslmode-explained) when connecting to a database over a network you don’t fully trust. Your best option is to connect over SSH or a VPN. Another option is to use `sslmode=verify-full`. If you don’t do this, your database credentials can be compromised.
|
338
|
+
|
339
|
+
## Homebrew
|
340
|
+
|
341
|
+
On Mac, you can use:
|
342
|
+
|
343
|
+
```sh
|
344
|
+
brew install ankane/brew/pgslice
|
345
|
+
```
|
346
|
+
|
347
|
+
## Dependencies
|
348
|
+
|
349
|
+
If installation fails, your system may be missing Ruby or libpq.
|
350
|
+
|
351
|
+
On Mac, run:
|
352
|
+
|
353
|
+
```sh
|
354
|
+
brew install postgresql
|
355
|
+
```
|
356
|
+
|
357
|
+
On Ubuntu, run:
|
358
|
+
|
359
|
+
```sh
|
360
|
+
sudo apt-get install ruby-dev libpq-dev build-essential
|
361
|
+
```
|
300
362
|
|
301
363
|
## Upgrading
|
302
364
|
|
@@ -331,6 +393,7 @@ This will give you the `pgslice` command.
|
|
331
393
|
|
332
394
|
Also check out:
|
333
395
|
|
396
|
+
- [Dexter](https://github.com/ankane/dexter) - The automatic indexer for Postgres
|
334
397
|
- [PgHero](https://github.com/ankane/pghero) - A performance dashboard for Postgres
|
335
398
|
- [pgsync](https://github.com/ankane/pgsync) - Sync Postgres data to your local machine
|
336
399
|
|
@@ -343,14 +406,14 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
|
|
343
406
|
- Write, clarify, or fix documentation
|
344
407
|
- Suggest or add new features
|
345
408
|
|
346
|
-
To
|
409
|
+
To get started with development:
|
347
410
|
|
348
411
|
```sh
|
349
412
|
git clone https://github.com/ankane/pgslice.git
|
350
413
|
cd pgslice
|
351
414
|
bundle install
|
352
415
|
createdb pgslice_test
|
353
|
-
bundle exec rake
|
416
|
+
bundle exec rake test
|
354
417
|
```
|
355
418
|
|
356
419
|
To test against different versions of Postgres with Docker, use:
|
data/exe/pgslice
CHANGED
@@ -4,6 +4,7 @@ module PgSlice
|
|
4
4
|
option :intermediate, type: :boolean, default: false, desc: "Add to intermediate table"
|
5
5
|
option :past, type: :numeric, default: 0, desc: "Number of past partitions to add"
|
6
6
|
option :future, type: :numeric, default: 0, desc: "Number of future partitions to add"
|
7
|
+
option :tablespace, type: :string, default: "", desc: "Tablespace to use"
|
7
8
|
def add_partitions(table)
|
8
9
|
original_table = create_table(table)
|
9
10
|
table = options[:intermediate] ? original_table.intermediate_table : original_table
|
@@ -13,6 +14,7 @@ module PgSlice
|
|
13
14
|
|
14
15
|
future = options[:future]
|
15
16
|
past = options[:past]
|
17
|
+
tablespace = options[:tablespace]
|
16
18
|
range = (-1 * past)..future
|
17
19
|
|
18
20
|
period, field, cast, needs_comment, declarative, version = table.fetch_settings(original_table.trigger_name)
|
@@ -50,6 +52,7 @@ module PgSlice
|
|
50
52
|
end
|
51
53
|
|
52
54
|
primary_key = schema_table.primary_key
|
55
|
+
tablespace_str = tablespace.empty? ? "" : " TABLESPACE #{quote_ident(tablespace)}"
|
53
56
|
|
54
57
|
added_partitions = []
|
55
58
|
range.each do |n|
|
@@ -61,13 +64,13 @@ module PgSlice
|
|
61
64
|
|
62
65
|
if declarative
|
63
66
|
queries << <<-SQL
|
64
|
-
CREATE TABLE #{quote_table(partition)} PARTITION OF #{quote_table(table)} FOR VALUES FROM (#{sql_date(day, cast, false)}) TO (#{sql_date(advance_date(day, period, 1), cast, false)});
|
67
|
+
CREATE TABLE #{quote_table(partition)} PARTITION OF #{quote_table(table)} FOR VALUES FROM (#{sql_date(day, cast, false)}) TO (#{sql_date(advance_date(day, period, 1), cast, false)})#{tablespace_str};
|
65
68
|
SQL
|
66
69
|
else
|
67
70
|
queries << <<-SQL
|
68
71
|
CREATE TABLE #{quote_table(partition)}
|
69
72
|
(CHECK (#{quote_ident(field)} >= #{sql_date(day, cast)} AND #{quote_ident(field)} < #{sql_date(advance_date(day, period, 1), cast)}))
|
70
|
-
INHERITS (#{quote_table(table)});
|
73
|
+
INHERITS (#{quote_table(table)})#{tablespace_str};
|
71
74
|
SQL
|
72
75
|
end
|
73
76
|
|
data/lib/pgslice/cli/swap.rb
CHANGED
@@ -17,7 +17,7 @@ module PgSlice
|
|
17
17
|
]
|
18
18
|
|
19
19
|
table.sequences.each do |sequence|
|
20
|
-
queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_table(table)}.#{quote_ident(sequence["related_column"])};"
|
20
|
+
queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_schema"])}.#{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_table(table)}.#{quote_ident(sequence["related_column"])};"
|
21
21
|
end
|
22
22
|
|
23
23
|
queries.unshift("SET LOCAL lock_timeout = '#{options[:lock_timeout]}';") if server_version_num >= 90300
|
data/lib/pgslice/cli/unswap.rb
CHANGED
@@ -16,7 +16,7 @@ module PgSlice
|
|
16
16
|
]
|
17
17
|
|
18
18
|
table.sequences.each do |sequence|
|
19
|
-
queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_table(table)}.#{quote_ident(sequence["related_column"])};"
|
19
|
+
queries << "ALTER SEQUENCE #{quote_ident(sequence["sequence_schema"])}.#{quote_ident(sequence["sequence_name"])} OWNED BY #{quote_table(table)}.#{quote_ident(sequence["related_column"])};"
|
20
20
|
end
|
21
21
|
|
22
22
|
run_queries(queries)
|
data/lib/pgslice/cli.rb
CHANGED
data/lib/pgslice/helpers.rb
CHANGED
@@ -33,10 +33,14 @@ module PgSlice
|
|
33
33
|
params = CGI.parse(uri.query.to_s)
|
34
34
|
# remove schema
|
35
35
|
@schema = Array(params.delete("schema") || "public")[0]
|
36
|
-
uri.query = URI.encode_www_form(params)
|
36
|
+
uri.query = params.any? ? URI.encode_www_form(params) : nil
|
37
37
|
|
38
38
|
ENV["PGCONNECT_TIMEOUT"] ||= "1"
|
39
|
-
PG::Connection.new(uri.to_s)
|
39
|
+
conn = PG::Connection.new(uri.to_s)
|
40
|
+
conn.set_notice_processor do |message|
|
41
|
+
say message
|
42
|
+
end
|
43
|
+
conn
|
40
44
|
end
|
41
45
|
rescue PG::ConnectionBad => e
|
42
46
|
abort e.message
|
data/lib/pgslice/table.rb
CHANGED
@@ -23,16 +23,19 @@ module PgSlice
|
|
23
23
|
def sequences
|
24
24
|
query = <<-SQL
|
25
25
|
SELECT
|
26
|
-
a.attname
|
27
|
-
|
26
|
+
a.attname AS related_column,
|
27
|
+
n.nspname AS sequence_schema,
|
28
|
+
s.relname AS sequence_name
|
28
29
|
FROM pg_class s
|
29
|
-
JOIN pg_depend d ON d.objid = s.oid
|
30
|
-
JOIN pg_class t ON d.objid = s.oid AND d.refobjid = t.oid
|
31
|
-
JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
|
32
|
-
JOIN pg_namespace n ON n.oid = s.relnamespace
|
30
|
+
INNER JOIN pg_depend d ON d.objid = s.oid
|
31
|
+
INNER JOIN pg_class t ON d.objid = s.oid AND d.refobjid = t.oid
|
32
|
+
INNER JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
|
33
|
+
INNER JOIN pg_namespace n ON n.oid = s.relnamespace
|
34
|
+
INNER JOIN pg_namespace nt ON nt.oid = t.relnamespace
|
33
35
|
WHERE s.relkind = 'S'
|
34
|
-
AND
|
36
|
+
AND nt.nspname = $1
|
35
37
|
AND t.relname = $2
|
38
|
+
ORDER BY s.relname ASC
|
36
39
|
SQL
|
37
40
|
execute(query, [schema, name])
|
38
41
|
end
|
@@ -41,12 +44,15 @@ module PgSlice
|
|
41
44
|
execute("SELECT pg_get_constraintdef(oid) FROM pg_constraint WHERE conrelid = #{regclass} AND contype ='f'").map { |r| r["pg_get_constraintdef"] }
|
42
45
|
end
|
43
46
|
|
44
|
-
#
|
47
|
+
# https://stackoverflow.com/a/20537829
|
48
|
+
# TODO can simplify with array_position in Postgres 9.5+
|
45
49
|
def primary_key
|
46
50
|
query = <<-SQL
|
47
51
|
SELECT
|
48
52
|
pg_attribute.attname,
|
49
|
-
format_type(pg_attribute.atttypid, pg_attribute.atttypmod)
|
53
|
+
format_type(pg_attribute.atttypid, pg_attribute.atttypmod),
|
54
|
+
pg_attribute.attnum,
|
55
|
+
pg_index.indkey
|
50
56
|
FROM
|
51
57
|
pg_index, pg_class, pg_attribute, pg_namespace
|
52
58
|
WHERE
|
@@ -58,7 +64,8 @@ module PgSlice
|
|
58
64
|
pg_attribute.attnum = any(pg_index.indkey) AND
|
59
65
|
indisprimary
|
60
66
|
SQL
|
61
|
-
execute(query, [schema, name])
|
67
|
+
rows = execute(query, [schema, name])
|
68
|
+
rows.sort_by { |r| r["indkey"].split(" ").index(r["attnum"]) }.map { |r| r["attname"] }
|
62
69
|
end
|
63
70
|
|
64
71
|
def index_defs
|
@@ -104,6 +111,7 @@ module PgSlice
|
|
104
111
|
(execute(query)[0]["min"] || 1).to_i
|
105
112
|
end
|
106
113
|
|
114
|
+
# ensure this returns partitions in the correct order
|
107
115
|
def partitions
|
108
116
|
query = <<-SQL
|
109
117
|
SELECT
|
@@ -117,6 +125,7 @@ module PgSlice
|
|
117
125
|
WHERE
|
118
126
|
nmsp_parent.nspname = $1 AND
|
119
127
|
parent.relname = $2
|
128
|
+
ORDER BY child.relname ASC
|
120
129
|
SQL
|
121
130
|
execute(query, [schema, name]).map { |r| Table.new(r["schema"], r["name"]) }
|
122
131
|
end
|
@@ -144,7 +153,7 @@ module PgSlice
|
|
144
153
|
function_def = execute("SELECT pg_get_functiondef(oid) FROM pg_proc WHERE proname = $1", [trigger_name])[0]
|
145
154
|
return [] unless function_def
|
146
155
|
function_def = function_def["pg_get_functiondef"]
|
147
|
-
sql_format = SQL_FORMAT.find { |_, f| function_def.include?("'#{f}'") }
|
156
|
+
sql_format = Helpers::SQL_FORMAT.find { |_, f| function_def.include?("'#{f}'") }
|
148
157
|
return [] unless sql_format
|
149
158
|
period = sql_format[0]
|
150
159
|
field = /to_char\(NEW\.(\w+),/.match(function_def)[1]
|
data/lib/pgslice/version.rb
CHANGED
data/lib/pgslice.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgslice
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -38,50 +38,8 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 0.18.2
|
41
|
-
|
42
|
-
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: rake
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: minitest
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
description:
|
84
|
-
email: andrew@chartkick.com
|
41
|
+
description:
|
42
|
+
email: andrew@ankane.org
|
85
43
|
executables:
|
86
44
|
- pgslice
|
87
45
|
extensions: []
|
@@ -107,7 +65,7 @@ homepage: https://github.com/ankane/pgslice
|
|
107
65
|
licenses:
|
108
66
|
- MIT
|
109
67
|
metadata: {}
|
110
|
-
post_install_message:
|
68
|
+
post_install_message:
|
111
69
|
rdoc_options: []
|
112
70
|
require_paths:
|
113
71
|
- lib
|
@@ -122,9 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
122
80
|
- !ruby/object:Gem::Version
|
123
81
|
version: '0'
|
124
82
|
requirements: []
|
125
|
-
|
126
|
-
|
127
|
-
signing_key:
|
83
|
+
rubygems_version: 3.3.3
|
84
|
+
signing_key:
|
128
85
|
specification_version: 4
|
129
86
|
summary: Postgres partitioning as easy as pie
|
130
87
|
test_files: []
|