Skip to content

Commit

Permalink
Add explain support (#8)
Browse files Browse the repository at this point in the history
* Add `explain` support
  • Loading branch information
kwong-yw authored Jun 17, 2022
1 parent 0a7933d commit 1b35c81
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 5 deletions.
14 changes: 10 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
### 2.0.0 / 2021-06-16
# Changelog
All notable changes to this project will be documented in this file.

* Change LICENSE to MIT (open source).
* This gem is now tested against Rubies 2.6, 2.7, and 3.0.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## 2.1.0 / 2022-06-17
* Add support for `EXPLAIN`.

### 1.0.0 / 2021-04-22 [Initial Release]
## 2.0.0 / 2021-06-16
* Change LICENSE to MIT (open source).
* This gem is now tested against Rubies 2.6, 2.7, and 3.0.

## 1.0.0 / 2021-04-22 [Initial Release]
* Handle parsing Snowflake values for the following types:
* Numeric data types
* String data types
Expand Down
2 changes: 1 addition & 1 deletion lib/sequel-snowflake/version.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Sequel
module Snowflake
# sequel-snowflake version
VERSION = "2.0.0"
VERSION = "2.1.0"
end
end
32 changes: 32 additions & 0 deletions lib/sequel/adapters/shared/snowflake.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module Sequel
module Snowflake
Sequel::Database.set_shared_adapter_scheme(:snowflake, self)

module DatasetMethods
# Return an array of strings specifying a query explanation for a SELECT of the
# current dataset.
# The options (symbolized, in lowercase) are:
# JSON: JSON output is easier to store in a table and query.
# TABULAR (default): tabular output is generally more human-readable than JSON output.
# TEXT: formatted text output is generally more human-readable than JSON output.
def explain(opts=OPTS)
# Load the PrettyTable class, needed for explain output
Sequel.extension(:_pretty_table) unless defined?(Sequel::PrettyTable)

explain_with_format = if opts[:tabular]
"EXPLAIN USING TABULAR"
elsif opts[:json]
"EXPLAIN USING JSON"
elsif opts[:text]
"EXPLAIN USING TEXT"
else
"EXPLAIN"
end

ds = db.send(:metadata_dataset).clone(:sql=>"#{explain_with_format} #{select_sql}")
rows = ds.all
Sequel::PrettyTable.string(rows, ds.columns)
end
end
end
end
3 changes: 3 additions & 0 deletions lib/sequel/adapters/snowflake.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'sequel'
require 'sequel/adapters/odbc'
require_relative 'shared/snowflake'

# A lightweight adapter providing Snowflake support for the `sequel` gem.
# The only difference between this and the Sequel-provided ODBC adapter is
Expand All @@ -20,6 +21,8 @@ def dataset_class_default

# A custom Sequel Dataset class crafted specifically to handle Snowflake results.
class Dataset < Sequel::ODBC::Dataset
include Sequel::Snowflake::DatasetMethods

def fetch_rows(sql)
execute(sql) do |s|
i = -1
Expand Down
32 changes: 32 additions & 0 deletions spec/sequel/adapters/snowflake_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,36 @@
expect(db[test_table].select(:n).all).to eq([{ n: 17 }, { n: 18 }])
end
end

describe '#explain' do
# Create a test table with a reasonably-random suffix
let!(:test_table) { "SEQUEL_SNOWFLAKE_SPECS_#{SecureRandom.hex(10)}".to_sym }
let!(:db) { Sequel.connect(adapter: :snowflake, drvconnect: ENV['SNOWFLAKE_CONN_STR']) }

before(:each) do
db.create_table(test_table, :temp => true) do
Numeric :id
String :name
String :email
String :title
end

db[test_table].insert(
{ id: 1, name: 'John Null', email: '[email protected]', title: 'Software Tester' }
)
end

after(:each) do
db.drop_table(test_table)
end

it "should have explain output" do
query = db.fetch("SELECT * FROM #{test_table} WHERE ID=1;")

expect(query.explain).to be_a_kind_of(String)
expect(query.explain(:tabular=>true)).to be_a_kind_of(String)
expect(query.explain(:json=>true)).to be_a_kind_of(String)
expect(query.explain(:text=>true)).to be_a_kind_of(String)
end
end
end

0 comments on commit 1b35c81

Please sign in to comment.