Skip to content

Commit b279c91

Browse files
authored
Merge pull request #317 from natebird/nulls_last_performance
Improve query performance when nulls_last option is enabled
2 parents 0aa6b48 + 5abe8a8 commit b279c91

File tree

4 files changed

+50
-15
lines changed

4 files changed

+50
-15
lines changed

lib/ajax-datatables-rails/datatable/simple_order.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@ def initialize(datatable, options = {})
1414
end
1515

1616
def query(sort_column)
17-
if sort_nulls_last?
18-
"CASE WHEN #{sort_column} IS NULL THEN 1 ELSE 0 END, #{sort_column} #{direction}"
19-
else
20-
"#{sort_column} #{direction}"
21-
end
17+
[sort_column, direction, nulls_last_sql].compact.join(" ")
2218
end
2319

2420
def column
@@ -43,6 +39,19 @@ def sort_nulls_last?
4339
column.nulls_last? || AjaxDatatablesRails.config.nulls_last == true
4440
end
4541

42+
def nulls_last_sql
43+
return unless sort_nulls_last?
44+
45+
case AjaxDatatablesRails.config.db_adapter
46+
when :pg, :postgresql, :postgres, :oracle
47+
"NULLS LAST"
48+
when :mysql, :mysql2, :sqlite, :sqlite3
49+
"IS NULL"
50+
else
51+
raise 'unsupported database adapter'
52+
end
53+
end
54+
4655
end
4756
end
4857
end

spec/ajax-datatables-rails/datatable/simple_order_spec.rb

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
it 'sql query' do
2121
expect(simple_order.query('email')).to eq(
22-
'CASE WHEN email IS NULL THEN 1 ELSE 0 END, email DESC'
22+
"email DESC #{nulls_last_sql}"
2323
)
2424
end
2525
end
@@ -28,12 +28,29 @@
2828
let(:sorted_datatable) { DatatableOrderNullsLast.new(sample_params).datatable }
2929
let(:nulls_last_order) { AjaxDatatablesRails::Datatable::SimpleOrder.new(sorted_datatable, options) }
3030

31-
it 'sql query' do
32-
expect(nulls_last_order.query('email')).to eq(
33-
'CASE WHEN email IS NULL THEN 1 ELSE 0 END, email DESC'
34-
)
31+
context 'with postgres database adapter' do
32+
before { AjaxDatatablesRails.config.db_adapter = :pg }
33+
34+
it 'sql query' do
35+
expect(nulls_last_order.query('email')).to eq('email DESC NULLS LAST')
36+
end
37+
end
38+
39+
context 'with sqlite database adapter' do
40+
before { AjaxDatatablesRails.config.db_adapter = :sqlite }
41+
42+
it 'sql query' do
43+
expect(nulls_last_order.query('email')).to eq('email DESC IS NULL')
44+
end
45+
end
46+
47+
context 'with mysql database adapter' do
48+
before { AjaxDatatablesRails.config.db_adapter = :mysql }
49+
50+
it 'sql query' do
51+
expect(nulls_last_order.query('email')).to eq('email DESC IS NULL')
52+
end
3553
end
3654
end
3755
end
38-
3956
end

spec/ajax-datatables-rails/orm/active_record_sort_records_spec.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@
5454
datatable.params[:order]['0'] = { column: '0', dir: 'asc' }
5555
datatable.params[:order]['1'] = { column: '1', dir: 'desc' }
5656
expect(datatable.sort_records(records).to_sql).to include(
57-
'ORDER BY CASE WHEN users.username IS NULL THEN 1 ELSE 0 END, users.username ASC, ' +
58-
'CASE WHEN users.email IS NULL THEN 1 ELSE 0 END, users.email DESC'
57+
"ORDER BY users.username ASC #{nulls_last_sql}, users.email DESC #{nulls_last_sql}"
5958
)
6059
end
6160
end
@@ -67,8 +66,7 @@
6766
nulls_last_datatable.params[:order]['0'] = { column: '0', dir: 'asc' }
6867
nulls_last_datatable.params[:order]['1'] = { column: '1', dir: 'desc' }
6968
expect(nulls_last_datatable.sort_records(records).to_sql).to include(
70-
'ORDER BY users.username ASC, ' +
71-
'CASE WHEN users.email IS NULL THEN 1 ELSE 0 END, users.email DESC'
69+
"ORDER BY users.username ASC, users.email DESC #{nulls_last_sql}"
7270
)
7371
end
7472
end

spec/support/test_helpers.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,14 @@ def data
9797
end
9898
end
9999
end
100+
101+
def nulls_last_sql
102+
case AjaxDatatablesRails.config.db_adapter
103+
when :pg, :postgresql, :postgres, :oracle
104+
"NULLS LAST"
105+
when :mysql, :mysql2, :sqlite, :sqlite3
106+
"IS NULL"
107+
else
108+
raise 'unsupported database adapter'
109+
end
110+
end

0 commit comments

Comments
 (0)