Ticket #9560: only_include_referenced_tables.diff
| File only_include_referenced_tables.diff, 3.3 kB (added by dasil003, 2 months ago) |
|---|
-
lib/active_record/associations.rb
old new 1388 1388 1389 1389 def construct_finder_sql_for_association_limiting(options, join_dependency) 1390 1390 scope = scope(:find) 1391 is_distinct = !options[:joins].blank? || include_eager_conditions?(options) || include_eager_order?(options) 1391 1392 # Only join tables referenced in order or conditions since this is particularly slow on the pre-query. 1393 tables_from_conditions = conditions_tables(options) 1394 tables_from_order = order_tables(options) 1395 all_tables = tables_from_conditions + tables_from_order 1396 1397 is_distinct = !options[:joins].blank? || include_eager_conditions?(options, tables_from_conditions) || include_eager_order?(options, tables_from_order) 1392 1398 sql = "SELECT " 1393 1399 if is_distinct 1394 1400 sql << connection.distinct("#{connection.quote_table_name table_name}.#{primary_key}", options[:order]) … … 1398 1404 sql << " FROM #{connection.quote_table_name table_name} " 1399 1405 1400 1406 if is_distinct 1401 sql << join_dependency.join_associations. collect(&:association_join).join1407 sql << join_dependency.join_associations.reject{ |ja| !all_tables.include?(ja.table_name) }.collect(&:association_join).join 1402 1408 add_joins!(sql, options, scope) 1403 1409 end 1404 1410 … … 1416 1422 return sanitize_sql(sql) 1417 1423 end 1418 1424 1419 # Checks if the conditions reference a table other than the current model table 1420 def include_eager_conditions?(options) 1425 def conditions_tables(options) 1421 1426 # look in both sets of conditions 1422 1427 conditions = [scope(:find, :conditions), options[:conditions]].inject([]) do |all, cond| 1423 1428 case cond … … 1426 1431 else all << cond 1427 1432 end 1428 1433 end 1429 return false unless conditions.any? 1430 conditions.join(' ').scan(/([\.\w]+).?\./).flatten.any? do |condition_table_name| 1434 conditions.join(' ').scan(/([\.\w]+).?\./).flatten 1435 end 1436 1437 def order_tables(options) 1438 order = options[:order] 1439 return [] unless order && order.is_a?(String) 1440 order.scan(/([\.\w]+).?\./).flatten 1441 end 1442 1443 # Checks if the conditions reference a table other than the current model table 1444 def include_eager_conditions?(options,tables = nil) 1445 tables = conditions_tables(options) 1446 return false unless tables.any? 1447 tables.any? do |condition_table_name| 1431 1448 condition_table_name != table_name 1432 1449 end 1433 1450 end 1434 1451 1435 1452 # Checks if the query order references a table other than the current model's table. 1436 def include_eager_order?(options )1437 order = options[:order]1438 return false unless order1439 order.to_s.scan(/([\.\w]+).?\./).flatten.any? do |order_table_name|1453 def include_eager_order?(options,tables = nil) 1454 tables = order_tables(options) 1455 return false unless tables.any? 1456 tables.any? do |order_table_name| 1440 1457 order_table_name != table_name 1441 1458 end 1442 1459 end