summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/database
diff options
context:
space:
mode:
authorAndreas Brandl <abrandl@gitlab.com>2018-10-28 19:16:47 +0100
committerAndreas Brandl <abrandl@gitlab.com>2018-12-03 21:26:50 +0100
commit3a7d9b4b02934c259fa2eda46143fa67320c2f5f (patch)
tree011da8a1dedf0da904f3c962ff3c90e46e869123 /spec/lib/gitlab/database
parentdce4a92bb06ae58e08bf104acc9b47a57f62c0dd (diff)
downloadgitlab-ce-3a7d9b4b02934c259fa2eda46143fa67320c2f5f.tar.gz
Implement TablesampleCountStrategy.
A tablesample count executes in two phases: * Estimate table sizes based on reltuples. * Based on the estimate: * If the table is considered 'small', execute an exact relation count. * Otherwise, count on a sample of the table using TABLESAMPLE. The size of the sample is chosen in a way that we always roughly scan the same amount of rows (see TABLESAMPLE_ROW_TARGET).
Diffstat (limited to 'spec/lib/gitlab/database')
-rw-r--r--spec/lib/gitlab/database/count_spec.rb53
1 files changed, 53 insertions, 0 deletions
diff --git a/spec/lib/gitlab/database/count_spec.rb b/spec/lib/gitlab/database/count_spec.rb
index 699422abb6b..d6668cee23e 100644
--- a/spec/lib/gitlab/database/count_spec.rb
+++ b/spec/lib/gitlab/database/count_spec.rb
@@ -123,4 +123,57 @@ describe Gitlab::Database::Count do
end
end
end
+
+ describe Gitlab::Database::Count::TablesampleCountStrategy do
+ subject { strategy.count }
+ let(:strategy) { described_class.new(models) }
+
+ describe '#count' do
+ let(:estimates) { { Project => threshold + 1, Identity => threshold - 1 } }
+ let(:threshold) { Gitlab::Database::Count::TablesampleCountStrategy::EXACT_COUNT_THRESHOLD }
+
+ before do
+ allow(strategy).to receive(:size_estimates).with(check_statistics: false).and_return(estimates)
+ end
+
+ context 'for tables with an estimated small size' do
+ it 'performs an exact count' do
+ expect(Identity).to receive(:count).and_call_original
+
+ expect(subject).to include({ Identity => 1 })
+ end
+ end
+
+ context 'for tables with an estimated large size' do
+ it 'performs a tablesample count' do
+ expect(Project).not_to receive(:count)
+
+ result = subject
+ expect(result[Project]).to eq(3)
+ end
+ end
+
+ context 'insufficient permissions' do
+ it 'returns an empty hash' do
+ allow(strategy).to receive(:size_estimates).and_raise(PG::InsufficientPrivilege)
+
+ expect(subject).to eq({})
+ end
+ end
+ end
+
+ describe '.enabled?' do
+ it 'is enabled for PostgreSQL' do
+ allow(Gitlab::Database).to receive(:postgresql?).and_return(true)
+
+ expect(described_class.enabled?).to be_truthy
+ end
+
+ it 'is disabled for MySQL' do
+ allow(Gitlab::Database).to receive(:postgresql?).and_return(false)
+
+ expect(described_class.enabled?).to be_falsey
+ end
+ end
+ end
end