Skip to content

Commit

Permalink
Merge pull request #362 from appbot/gsi-hash-key-overlap
Browse files Browse the repository at this point in the history
Handle edge case where there is a GSI with the same hash key as primary
  • Loading branch information
andrykonchin committed Jun 10, 2019
2 parents ae9152f + 17ae990 commit 0afb3aa
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 3 deletions.
4 changes: 1 addition & 3 deletions lib/dynamoid/criteria/key_fields_detector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ def detect_keys
@range_key = lsi.range_key
@index_name = lsi.name
end

return
end

# See if can use any global secondary index
Expand All @@ -49,7 +47,7 @@ def detect_keys
# get back full data
@source.global_secondary_indexes.each do |_, gsi|
next unless @query.keys.map(&:to_s).include?(gsi.hash_key.to_s) && gsi.projected_attributes == :all
next if @range_key.present? && !query_keys.include?(gsi.range_key.to_s)
next if @hash_key.present? && !query_keys.include?(gsi.range_key.to_s)

@hash_key = gsi.hash_key
@range_key = gsi.range_key
Expand Down
10 changes: 10 additions & 0 deletions spec/dynamoid/criteria/chain_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ def request_params
global_secondary_index hash_key: :city, range_key: :age, name: :cityage, projected_attributes: :all
global_secondary_index hash_key: :city, range_key: :gender, name: :citygender, projected_attributes: :all
global_secondary_index hash_key: :email, range_key: :age, name: :emailage, projected_attributes: :all
global_secondary_index hash_key: :name, range_key: :age, name: :nameage, projected_attributes: :all
end
end

Expand Down Expand Up @@ -766,6 +767,15 @@ def request_params
expect(chain.key_fields_detector.range_key).to eq(:gender)
expect(chain.key_fields_detector.index_name).to eq(:citygender)
end

it 'uses global secondary index when secondary hash key overlaps with primary hash key and range key matches' do
chain = Dynamoid::Criteria::Chain.new(model)
expect(chain).to receive(:pages_via_query).and_call_original
expect(chain.where(name: 'Bob', age: 10).to_a.size).to eq(1)
expect(chain.key_fields_detector.hash_key).to eq(:name)
expect(chain.key_fields_detector.range_key).to eq(:age)
expect(chain.key_fields_detector.index_name).to eq(:nameage)
end
end

it 'supports query on global secondary index with correct start key without table range key' do
Expand Down

0 comments on commit 0afb3aa

Please sign in to comment.