diff --git a/lib/ddtrace/contrib/sequel/database.rb b/lib/ddtrace/contrib/sequel/database.rb index e32d395682d..eed4cae91e8 100644 --- a/lib/ddtrace/contrib/sequel/database.rb +++ b/lib/ddtrace/contrib/sequel/database.rb @@ -52,6 +52,8 @@ def parse_opts(sql, opts) elsif instance_variable_defined?(:@pool) && @pool @pool.db.opts end + sql = sql.is_a?(::Sequel::SQL::Expression) ? literal(sql) : sql.to_s + Utils.parse_opts(sql, opts, db_opts) end end diff --git a/spec/ddtrace/contrib/sequel/instrumentation_spec.rb b/spec/ddtrace/contrib/sequel/instrumentation_spec.rb index bf93328babc..0982b98fc7b 100644 --- a/spec/ddtrace/contrib/sequel/instrumentation_spec.rb +++ b/spec/ddtrace/contrib/sequel/instrumentation_spec.rb @@ -35,6 +35,7 @@ around do |example| # Reset before and after each example; don't allow global state to linger. Datadog.registry[:sequel].reset_configuration! + Sequel::DATABASES.each(&:disconnect) example.run Datadog.registry[:sequel].reset_configuration! end @@ -48,31 +49,46 @@ let(:normalized_adapter) { defined?(super) ? super() : adapter } - describe 'when queried through a Sequel::Database object' do - before(:each) { sequel.run(query) } - let(:query) { "SELECT * FROM tbl WHERE name = 'foo'" } - let(:span) { spans.first } - - it 'traces the command' do - expect(span.name).to eq('sequel.query') - # Expect it to be the normalized adapter name. - expect(span.service).to eq(normalized_adapter) - expect(span.span_type).to eq('sql') - expect(span.get_tag('sequel.db.vendor')).to eq(normalized_adapter) - # Expect non-quantized query: agent does SQL quantization. - expect(span.resource).to eq(query) - expect(span.status).to eq(0) - expect(span.parent_id).to eq(0) - end + describe 'Sequel::Database.run' do + shared_context 'query executed through a Sequel::Database object' do + before(:each) { sequel.run(query) } + let(:span) { spans.first } - it_behaves_like 'analytics for integration' do - let(:analytics_enabled_var) { Datadog::Contrib::Sequel::Ext::ENV_ANALYTICS_ENABLED } - let(:analytics_sample_rate_var) { Datadog::Contrib::Sequel::Ext::ENV_ANALYTICS_SAMPLE_RATE } + it 'traces the command' do + expect(span.name).to eq('sequel.query') + # Expect it to be the normalized adapter name. + expect(span.service).to eq(normalized_adapter) + expect(span.span_type).to eq('sql') + expect(span.get_tag('sequel.db.vendor')).to eq(normalized_adapter) + # Expect non-quantized query: agent does SQL quantization. + expect(span.resource).to eq(expected_query) + expect(span.status).to eq(0) + expect(span.parent_id).to eq(0) + end + + it_behaves_like 'analytics for integration' do + let(:analytics_enabled_var) { Datadog::Contrib::Sequel::Ext::ENV_ANALYTICS_ENABLED } + let(:analytics_sample_rate_var) { Datadog::Contrib::Sequel::Ext::ENV_ANALYTICS_SAMPLE_RATE } + end + + it_behaves_like 'a peer service span' + + it_behaves_like 'measured span for integration', false end - it_behaves_like 'a peer service span' + context 'with query provided as a string' do + it_behaves_like 'query executed through a Sequel::Database object' do + let(:query) { "SELECT * FROM tbl WHERE name = 'foo'" } + let(:expected_query) { query } + end + end - it_behaves_like 'measured span for integration', false + context 'with query provided as complex expression' do + it_behaves_like 'query executed through a Sequel::Database object' do + let(:query) { Sequel.lit('SELECT * FROM tbl WHERE name = :var', var: 'foo') } + let(:expected_query) { sequel.literal(query) } + end + end end describe 'when queried through a Sequel::Dataset' do