pgdexter 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c68746f6134f6603c5549b561886b45ee3432df5d1e07e65a5907559901d333a
4
- data.tar.gz: 699c2744f3e2c9a79f8fa9ca6ae7a77586421243cbf7a1f92642f76724cc0cb0
3
+ metadata.gz: e51edc18f4049b9ca811e4662248aa7a23e748b000975a87fa4a431f49ec632b
4
+ data.tar.gz: f3aa243431e0aab1d84d4cbc48ee6a329581acedc7a9c70e2a13e7bb0e15b529
5
5
  SHA512:
6
- metadata.gz: 343bc52539ef09541fd0774667034ea02fb88b0e4f820e52c86d77df46d059c253576c22272b91a407b764965f66c554278154da6ab923249ce9979ab3a5aed0
7
- data.tar.gz: a9b86931b4fc58d2b89c87f46f5008dfd47274cc39f096ec2b5143bea8858e29a786e387f9ccc29fe74475b5b0317e9d348d36f2a686cb19457ee79179a270f5
6
+ metadata.gz: 67b04a3c336c3bec239490a386825153699c646a01f5fe30d84b42445695f2431b1545bace72c5b955e03e92ad531810b5a73971d559abb06f175a1965454b89
7
+ data.tar.gz: 63691b01566b54056201c2d0a5c73a8153252b7c2ce4619983feb3b20e58d49d4a738b210be61d46231d3b5c78c1787664c625c0eb0216ee0d9ba19dcc8a7621
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 0.5.2 (2024-01-10)
2
+
3
+ - Added Docker image for `linux/arm64`
4
+ - Switched to `GENERIC_PLAN` for Postgres 16
5
+ - Fixed error with `auto_explain`
6
+ - Fixed warning with Ruby 3.3
7
+
1
8
  ## 0.5.1 (2023-05-27)
2
9
 
3
10
  - Fixed `JSON::NestingError`
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2023 Andrew Kane
1
+ Copyright (c) 2017-2024 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -4,7 +4,7 @@ The automatic indexer for Postgres
4
4
 
5
5
  [Read about how it works](https://ankane.org/introducing-dexter) or [watch the talk](https://www.youtube.com/watch?v=Mni_1yTaNbE)
6
6
 
7
- [![Build Status](https://github.com/ankane/dexter/workflows/build/badge.svg?branch=master)](https://github.com/ankane/dexter/actions)
7
+ [![Build Status](https://github.com/ankane/dexter/actions/workflows/build.yml/badge.svg)](https://github.com/ankane/dexter/actions)
8
8
 
9
9
  ## Installation
10
10
 
@@ -185,7 +185,7 @@ module Dexter
185
185
 
186
186
  # get initial costs for queries
187
187
  calculate_plan(queries)
188
- explainable_queries = queries.select { |q| q.explainable? && q.high_cost? }
188
+ explainable_queries = queries.select { |q| q.plans.any? && q.high_cost? }
189
189
 
190
190
  # filter tables for performance
191
191
  tables = Set.new(explainable_queries.flat_map(&:tables))
@@ -521,8 +521,8 @@ module Dexter
521
521
  raise Dexter::Abort, e.message
522
522
  end
523
523
 
524
- def execute(query, pretty: true, params: [])
525
- # use exec_params instead of exec for security
524
+ def execute(query, pretty: true, params: [], use_exec: false)
525
+ # use exec_params instead of exec when possible for security
526
526
  #
527
527
  # Unlike PQexec, PQexecParams allows at most one SQL command in the given string.
528
528
  # (There can be semicolons in it, but not more than one nonempty command.)
@@ -533,7 +533,11 @@ module Dexter
533
533
  log colorize("[sql] #{query}#{params.any? ? " /*#{params.to_json}*/" : ""}", :cyan) if @log_sql
534
534
 
535
535
  @mutex.synchronize do
536
- conn.exec_params("#{query} /*dexter*/", params).to_a
536
+ if use_exec
537
+ conn.exec("#{query} /*dexter*/").to_a
538
+ else
539
+ conn.exec_params("#{query} /*dexter*/", params).to_a
540
+ end
537
541
  end
538
542
  end
539
543
 
@@ -543,7 +547,9 @@ module Dexter
543
547
 
544
548
  # try to EXPLAIN normalized queries
545
549
  # https://dev.to/yugabyte/explain-from-pgstatstatements-normalized-queries-how-to-always-get-the-generic-plan-in--5cfi
546
- explain_normalized = query.include?("$1")
550
+ normalized = query.include?("$1")
551
+ generic_plan = normalized && server_version_num >= 160000
552
+ explain_normalized = normalized && !generic_plan
547
553
  if explain_normalized
548
554
  prepared_name = "dexter_prepared"
549
555
  execute("PREPARE #{prepared_name} AS #{safe_statement(query)}", pretty: false)
@@ -566,12 +572,14 @@ module Dexter
566
572
  end
567
573
  end
568
574
 
575
+ explain_prefix = generic_plan ? "GENERIC_PLAN, " : ""
576
+
569
577
  # strip semi-colons as another measure of defense
570
- plan = JSON.parse(execute("EXPLAIN (FORMAT JSON) #{safe_statement(query)}", pretty: false).first["QUERY PLAN"], max_nesting: 1000).first["Plan"]
578
+ plan = JSON.parse(execute("EXPLAIN (#{explain_prefix}FORMAT JSON) #{safe_statement(query)}", pretty: false, use_exec: generic_plan).first["QUERY PLAN"], max_nesting: 1000).first["Plan"]
571
579
 
572
580
  if @log_explain
573
581
  # Pass format to prevent ANALYZE
574
- puts execute("EXPLAIN (FORMAT TEXT) #{safe_statement(query)}", pretty: false).map { |r| r["QUERY PLAN"] }.join("\n")
582
+ puts execute("EXPLAIN (#{explain_prefix}FORMAT TEXT) #{safe_statement(query)}", pretty: false, use_exec: generic_plan).map { |r| r["QUERY PLAN"] }.join("\n")
575
583
  end
576
584
 
577
585
  plan
data/lib/dexter/query.rb CHANGED
@@ -31,7 +31,7 @@ module Dexter
31
31
  end
32
32
 
33
33
  def explainable?
34
- plans.any?
34
+ plans.size >= 3
35
35
  end
36
36
 
37
37
  def costs
@@ -1,3 +1,3 @@
1
1
  module Dexter
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pgdexter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-27 00:00:00.000000000 Z
11
+ date: 2024-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: csv
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: pg
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -96,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
110
  - !ruby/object:Gem::Version
97
111
  version: '0'
98
112
  requirements: []
99
- rubygems_version: 3.4.10
113
+ rubygems_version: 3.5.3
100
114
  signing_key:
101
115
  specification_version: 4
102
116
  summary: The automatic indexer for Postgres