Skip to content

Commit 1d81596

Browse files
committed
Switch PostgreSQL Database#indexes :include_invalid option to :invalid
The :include_invalid support has been switched to invalid: :include. This adds support for requesting only invalid indexes using invalid: :only. I probably should have done something similar when adding support for partial indexes. This doesn't change the :include_partial option to :partial (that wouldn't be backwards compatible), though I'm willing to add support for partial: :include and partial: :only if anyone wants that ability. This removes the :include_invalid spec instead of modifying it. The spec only worked correctly if the user running the specs is the database superuser. That may be true in CI, but it's not recommended for standard testing during development. I'm not sure how to force an invalid index in all supported PostgreSQL versions, and since this updates the add_index :only option specs to test the indexes :invalid option, I don't think the separate spec is needed. Since it's simple, add a mock adpater spec for use of the add_index :only option.
1 parent fb92764 commit 1d81596

File tree

5 files changed

+44
-17
lines changed

5 files changed

+44
-17
lines changed

CHANGELOG

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
=== master
2+
3+
* Add support for Database#create_index :only option on PostgreSQL 11+ (KirIgor) (#2343)
4+
5+
* Add support for Database#indexes :invalid option on PostgresSQL (KirIgor, jeremyevans) (#2343)
6+
17
=== 5.98.0 (2025-11-01)
28

39
* Make insert_returning_select use RETURNING when using table_select plugin (jeremyevans) (#2339)

doc/postgresql.rdoc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -555,9 +555,11 @@ handle locking:
555555

556556
== PostgreSQL-specific reflection Support
557557

558-
The Database#indexes method supports the options :include_partial and :include_invalid.
559-
These options allow partial and invalid indexes to be included in the results, respectively.
560-
By default, Sequel excludes both partial and invalid indexes.
558+
The Database#indexes method supports the options :include_partial and :invalid.
559+
These options allows partial indexes to be included and invalid indexes to be
560+
included in the results (`invalid: :include`) or to only return invalid indexes
561+
(`invalid: :only`), respectively. By default, Sequel excludes both partial and
562+
invalid indexes.
561563

562564
== Extended Error Info (<tt>postgres/pg only</tt>)
563565

lib/sequel/adapters/shared/postgres.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,12 +669,25 @@ def immediate_constraints(opts=OPTS)
669669
_set_constraints(' IMMEDIATE', opts)
670670
end
671671

672-
# Use the pg_* system tables to determine indexes on a table
672+
# Use the pg_* system tables to determine indexes on a table. Options:
673+
#
674+
# :include_partial :: Set to true to include partial indexes
675+
# :invalid :: Set to true or :only to only return invalid indexes.
676+
# Set to :include to also return both valid and invalid indexes.
677+
# When not set or other value given, does not return invalid indexes.
673678
def indexes(table, opts=OPTS)
674679
m = output_identifier_meth
675680
cond = {Sequel[:tab][:oid]=>regclass_oid(table, opts)}
676681
cond[:indpred] = nil unless opts[:include_partial]
677-
cond[:indisvalid] = true unless opts[:include_invalid]
682+
683+
case opts[:invalid]
684+
when true, :only
685+
cond[:indisvalid] = false
686+
when :include
687+
# nothing
688+
else
689+
cond[:indisvalid] = true
690+
end
678691

679692
indexes = {}
680693
_indexes_ds.where_each(cond) do |r|

spec/adapters/postgres_spec.rb

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,13 +1576,6 @@ def before_create
15761576
@db.indexes(:test, :include_partial=>true)[:tnv_partial].must_equal(:columns=>[:name, :value], :unique=>false, :deferrable=>nil)
15771577
end
15781578

1579-
it "should support parsing invalid indexes with :include_invalid option" do
1580-
@db.add_index :test, [:name, :value], :name=>:tnv_invalid
1581-
@db.run("UPDATE pg_index SET indisvalid = false WHERE indexrelid = 'tnv_invalid'::regclass;")
1582-
@db.indexes(:test)[:tnv_invalid].must_be_nil
1583-
@db.indexes(:test, :include_invalid=>true)[:tnv_invalid].must_equal(:columns=>[:name, :value], :unique=>false, :deferrable=>nil)
1584-
end
1585-
15861579
it "should support creating indexes concurrently" do
15871580
@db.add_index :test, [:name, :value], :concurrently=>true, :name=>'tnv0'
15881581
end
@@ -1642,12 +1635,20 @@ def before_create
16421635
end
16431636

16441637
it "should support creating indexes with ONLY option" do
1645-
@db.create_table(:atest, partition_by: :id, :partition_type=>:range){Integer :id}
1638+
@db.create_table(:atest, partition_by: :id, :partition_type=>:range){Integer :id; String :name}
16461639
@db.create_table(:btest, partition_of: :atest){from 1; to 3}
1647-
@db.add_index :atest, :id, :only=>true
1648-
1649-
@db.indexes(:atest, :include_invalid=>true).size.must_equal 1
1650-
@db.indexes(:btest, :include_invalid=>true).must_be_empty
1640+
@db.add_index :atest, :id, :only=>true, :name=>:atest_id_only_idx
1641+
@db.add_index :atest, :name, :name=>:atest_name_only_idx
1642+
1643+
@db.indexes(:atest).keys.must_equal [:atest_name_only_idx]
1644+
@db.indexes(:atest, :invalid=>true).keys.must_equal [:atest_id_only_idx]
1645+
@db.indexes(:atest, :invalid=>:only).keys.must_equal [:atest_id_only_idx]
1646+
@db.indexes(:atest, :invalid=>:include).keys.sort.must_equal [:atest_id_only_idx, :atest_name_only_idx]
1647+
1648+
@db.indexes(:btest).keys.must_equal [:btest_name_idx]
1649+
@db.indexes(:btest, :invalid=>true).keys.must_equal []
1650+
@db.indexes(:btest, :invalid=>:only).keys.must_equal []
1651+
@db.indexes(:btest, :invalid=>:include).keys.sort.must_equal [:btest_name_idx]
16511652
end if DB.server_version >= 110000
16521653

16531654
it "#lock should lock table if inside a transaction" do

spec/core/mock_adapter_spec.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,11 @@ def a.method_missing(m, *x) push(*x) end
627627
@db.sqls.must_equal ['CREATE INDEX "posts_user_id_index" ON "posts" USING btree ("user_id" int4_ops)']
628628
end
629629

630+
it "should support add_index :only option" do
631+
@db.alter_table(:posts){add_index(:user_id, :only=> true)}
632+
@db.sqls.must_equal ['CREATE INDEX "posts_user_id_index" ON ONLY "posts" ("user_id")']
633+
end
634+
630635
it 'should quote NaN' do
631636
nan = 0.0/0.0
632637
@db[:test5].insert_sql(:value => nan).must_equal %q{INSERT INTO "test5" ("value") VALUES ('NaN')}

0 commit comments

Comments
 (0)