From 7dfdbaba8c2cc1c40313e30a1d8bb8b2bf34b5e8 Mon Sep 17 00:00:00 2001 From: Ethan Donowitz Date: Tue, 2 Jan 2024 16:22:00 -0500 Subject: [PATCH] relation: Add .readyset_explain This commit adds a `.readyset_explain` method to our relation extension. This method invokes `EXPLAIN CREATE CACHE` upstream on ReadySet and returns information about the query from ReadySet. --- lib/readyset/relation_extension.rb | 12 +++++++++-- spec/relation_extension_spec.rb | 32 ++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/readyset/relation_extension.rb b/lib/readyset/relation_extension.rb index f3eaa16..75a8283 100644 --- a/lib/readyset/relation_extension.rb +++ b/lib/readyset/relation_extension.rb @@ -7,7 +7,7 @@ module RelationExtension # query already exists. # # NOTE: If the ActiveRecord query eager loads associations (e.g. via `#includes`), the - # the queries issues to do the eager loading will not have caches created. Those queries must + # the queries issued to do the eager loading will not have caches created. Those queries must # have their caches created separately. # # @return [void] @@ -19,13 +19,21 @@ def create_readyset_cache! # for the query already doesn't exist. # # NOTE: If the ActiveRecord query eager loads associations (e.g. via `#includes`), the - # the queries issues to do the eager loading will not have caches dropped. Those queries must + # the queries issued to do the eager loading will not have caches dropped. Those queries must # have their caches dropped separately. # # @return [void] def drop_readyset_cache! Readyset.drop_cache!(sql: to_sql) end + + # Gets information about this query from ReadySet, including the query's ID, the normalized + # query text, and whether the query is supported by ReadySet. + # + # @return [Readyset::Explain] + def readyset_explain + Readyset.explain(to_sql) + end end end end diff --git a/spec/relation_extension_spec.rb b/spec/relation_extension_spec.rb index 476116c..a780888 100644 --- a/spec/relation_extension_spec.rb +++ b/spec/relation_extension_spec.rb @@ -12,8 +12,7 @@ subject end - it 'invokes `Readyset.create_cache!` with the parameterized query string that the ' \ - 'relation represents' do + it "invokes `Readyset.create_cache!` with the relation's query string" do expect(Readyset).to have_received(:create_cache!).with(sql: query_string) end end @@ -29,9 +28,34 @@ subject end - it 'invokes `Readyset.drop_cache!` with the parameterized query string that the relation ' \ - 'represents' do + it "invokes `Readyset.drop_cache!` with the relation's query string" do expect(Readyset).to have_received(:drop_cache!).with(sql: query_string) end end + + describe '#readyset_explain' do + it "invokes `Readyset.readyset_explain` with the relation's query string" do + query = Cat.where(id: 1) + query_string = query.to_sql + allow(Readyset).to receive(:explain).with(query_string). + and_return(instance_double(Readyset::Explain)) + + query.readyset_explain + + expect(Readyset).to have_received(:explain).with(query_string) + end + + it 'returns the expected explain information' do + query = Cat.where(id: 1) + query_string = query.to_sql + explain = Readyset::Explain.new(id: 'q_0000000000000000', + text: 'SELECT * FROM "cats" WHERE ("id" = $1)', + supported: :yes) + allow(Readyset).to receive(:explain).with(query_string).and_return(explain) + + output = query.readyset_explain + + expect(output).to eq(explain) + end + end end