altertable-lakehouse 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f2f1d437eff964062288c5b189001c85a1954e7b95e1a91646f792d6886d0d1
4
- data.tar.gz: 68037c1a228479878bb023f0532b4f91e8f005a065ac8473c42d62ba3ce4f8f5
3
+ metadata.gz: 6a4112edc1eff1c9caeed879ce5e7331f6e55837d59e2b715e5e32947f51f237
4
+ data.tar.gz: 72ae2b506a9ee60fe1a9244f976c2af4a407bc70805f4636e45dfc0505cf3bac
5
5
  SHA512:
6
- metadata.gz: 48c13e24a29727a0dd957053558b7e47d74eefcd651fe12a8b81c8cd912073c75c7f42c00c1a29d8e7ed231665541ea602ff2cb9a86affef3b40825d775d0f91
7
- data.tar.gz: 3f3f3e6b41468ed309266855c88f60e729022dbd2bb638c8c9c88b8f7baf861dc84b3fdd886dd8a098b3000d9cb339d1ffd9c8cec7fe82103da52a3fedc496fd
6
+ metadata.gz: 5db5a3aea35032b994a7f905463d084636c3b17add02dce0313d3dd9cd5a8f21ed32046e4a3cef598fc30d2e43ba2a0c46acc57688ca3b358ec2c3546edbe39a
7
+ data.tar.gz: 8f22a1b33fdd3f446dd627cc31f4d702614530c3c0c1df90eac4c4fe6367fc0301c97e130b6f235e4fba3610446daff1d12d786cb9e88bee9d9514dc61039441
@@ -3,9 +3,7 @@ name: CI
3
3
  on:
4
4
  push:
5
5
  branches: [main]
6
- pull_request:
7
- branches: [main]
8
-
6
+ pull_request: {}
9
7
  jobs:
10
8
  test:
11
9
  runs-on: ubuntu-latest
@@ -52,3 +50,18 @@ jobs:
52
50
  bundler-cache: true
53
51
  - name: Run RuboCop
54
52
  run: bundle exec rubocop
53
+
54
+ typing:
55
+ name: "Typing"
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v4
59
+ - name: Set up Ruby
60
+ uses: ruby/setup-ruby@v1
61
+ with:
62
+ ruby-version: "3.4"
63
+ bundler-cache: true
64
+ - name: Validate RBS
65
+ run: bundle exec rbs validate
66
+ - name: Typecheck with Sorbet
67
+ run: bundle exec srb tc
@@ -0,0 +1,29 @@
1
+ name: Semantic Pull Request
2
+ on:
3
+ pull_request_target:
4
+ types:
5
+ - opened
6
+ - edited
7
+ - synchronize
8
+
9
+ jobs:
10
+ main:
11
+ name: Validate PR title
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: amannn/action-semantic-pull-request@v5
15
+ env:
16
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
17
+ with:
18
+ types: |
19
+ feat
20
+ fix
21
+ perf
22
+ revert
23
+ docs
24
+ style
25
+ chore
26
+ refactor
27
+ test
28
+ build
29
+ ci
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.3.0"
2
+ ".": "0.4.1"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.4.1](https://github.com/altertable-ai/altertable-lakehouse-ruby/compare/altertable-lakehouse/v0.4.0...altertable-lakehouse/v0.4.1) (2026-05-27)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **rbi:** rework RBI syntax & nested types ([#33](https://github.com/altertable-ai/altertable-lakehouse-ruby/issues/33)) ([4845ab1](https://github.com/altertable-ai/altertable-lakehouse-ruby/commit/4845ab1dbb1bfbac04eb4629b0f81ce0e4422e0d))
11
+
12
+ ## [0.4.0](https://github.com/altertable-ai/altertable-lakehouse-ruby/compare/altertable-lakehouse/v0.3.0...altertable-lakehouse/v0.4.0) (2026-05-27)
13
+
14
+
15
+ ### Features
16
+
17
+ * add v0.11.0 lakehouse operations ([#27](https://github.com/altertable-ai/altertable-lakehouse-ruby/issues/27)) ([cc52dbb](https://github.com/altertable-ai/altertable-lakehouse-ruby/commit/cc52dbb4ef995b027697f6fa68164f6704e02058))
18
+ * **explain:** add /explain support ([#31](https://github.com/altertable-ai/altertable-lakehouse-ruby/issues/31)) ([b326e94](https://github.com/altertable-ai/altertable-lakehouse-ruby/commit/b326e949742f9f4c89e5ea2aeb67028513e8a118))
19
+ * **typings:** add RBI & RBS typings ([#29](https://github.com/altertable-ai/altertable-lakehouse-ruby/issues/29)) ([c569e6d](https://github.com/altertable-ai/altertable-lakehouse-ruby/commit/c569e6d58c1c36af2f51a329591eebd2e0677d17))
20
+
5
21
  ## [0.3.0](https://github.com/altertable-ai/altertable-lakehouse-ruby/compare/altertable-lakehouse-v0.2.0...altertable-lakehouse/v0.3.0) (2026-03-08)
6
22
 
7
23
 
data/Gemfile CHANGED
@@ -5,3 +5,5 @@ gemspec
5
5
  gem "rake", "~> 13.0"
6
6
  gem "rspec", "~> 3.0"
7
7
  gem "faraday-net_http"
8
+
9
+ gem "tapioca", require: false, group: %i[development test]
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- altertable-lakehouse (0.3.0)
4
+ altertable-lakehouse (0.4.1)
5
5
  base64
6
6
 
7
7
  GEM
@@ -11,11 +11,13 @@ GEM
11
11
  public_suffix (>= 2.0.2, < 8.0)
12
12
  ast (2.4.3)
13
13
  base64 (0.3.0)
14
+ benchmark (0.5.0)
14
15
  bigdecimal (4.0.1)
15
16
  diff-lcs (1.6.2)
16
17
  docker-api (2.4.0)
17
18
  excon (>= 0.64.0)
18
19
  multi_json
20
+ erubi (1.13.1)
19
21
  excon (1.4.0)
20
22
  logger
21
23
  faraday (2.14.1)
@@ -41,6 +43,7 @@ GEM
41
43
  multi_json (1.19.1)
42
44
  net-http (0.9.1)
43
45
  uri (>= 0.11.1)
46
+ netrc (0.11.0)
44
47
  parallel (1.27.0)
45
48
  parser (3.3.10.2)
46
49
  ast (~> 2.4.1)
@@ -50,7 +53,16 @@ GEM
50
53
  racc (1.8.1)
51
54
  rainbow (3.1.1)
52
55
  rake (13.3.1)
56
+ rbi (0.3.9)
57
+ prism (~> 1.0)
58
+ rbs (>= 3.4.4)
59
+ rbs (4.0.2)
60
+ logger
61
+ prism (>= 1.6.0)
62
+ tsort
53
63
  regexp_parser (2.11.3)
64
+ require-hooks (0.2.2)
65
+ rexml (3.4.4)
54
66
  rspec (3.13.2)
55
67
  rspec-core (~> 3.13.0)
56
68
  rspec-expectations (~> 3.13.0)
@@ -80,18 +92,49 @@ GEM
80
92
  parser (>= 3.3.7.2)
81
93
  prism (~> 1.7)
82
94
  ruby-progressbar (1.13.0)
95
+ sorbet (0.6.12997)
96
+ sorbet-static (= 0.6.12997)
97
+ sorbet-runtime (0.6.12997)
98
+ sorbet-static (0.6.12997-universal-darwin)
99
+ sorbet-static-and-runtime (0.6.12997)
100
+ sorbet (= 0.6.12997)
101
+ sorbet-runtime (= 0.6.12997)
102
+ spoom (1.7.8)
103
+ erubi (>= 1.10.0)
104
+ prism (>= 0.28.0)
105
+ rbi (>= 0.3.3)
106
+ rbs (>= 4.0.0.dev.4)
107
+ rexml (>= 3.2.6)
108
+ sorbet-static-and-runtime (>= 0.5.10187)
109
+ thor (>= 0.19.2)
110
+ tapioca (0.17.7)
111
+ benchmark
112
+ bundler (>= 2.2.25)
113
+ netrc (>= 0.11.0)
114
+ parallel (>= 1.21.0)
115
+ rbi (>= 0.3.1)
116
+ require-hooks (>= 0.2.2)
117
+ sorbet-static-and-runtime (>= 0.5.11087)
118
+ spoom (>= 1.7.0)
119
+ thor (>= 1.2.0)
120
+ yard-sorbet
83
121
  testcontainers (0.2.0)
84
122
  testcontainers-core (= 0.2.0)
85
123
  testcontainers-core (0.2.0)
86
124
  docker-api (~> 2.2)
125
+ thor (1.5.0)
126
+ tsort (0.2.0)
87
127
  unicode-display_width (3.2.0)
88
128
  unicode-emoji (~> 4.1)
89
129
  unicode-emoji (4.2.0)
90
130
  uri (1.1.1)
131
+ yard (0.9.43)
132
+ yard-sorbet (0.9.0)
133
+ sorbet-runtime
134
+ yard
91
135
 
92
136
  PLATFORMS
93
137
  arm64-darwin-25
94
- ruby
95
138
  x86_64-linux
96
139
 
97
140
  DEPENDENCIES
@@ -101,8 +144,12 @@ DEPENDENCIES
101
144
  faraday-retry (~> 2.0)
102
145
  httpx
103
146
  rake (~> 13.0)
147
+ rbs
104
148
  rspec (~> 3.0)
105
149
  rubocop (~> 1.50)
150
+ sorbet
151
+ sorbet-runtime
152
+ tapioca
106
153
  testcontainers
107
154
 
108
155
  BUNDLED WITH
data/README.md CHANGED
@@ -34,7 +34,8 @@ client.append(
34
34
  catalog: "main",
35
35
  schema: "public",
36
36
  table: "events",
37
- payload: { user_id: 123, event: "signup", timestamp: Time.now.iso8601 }
37
+ payload: { user_id: 123, event: "signup", timestamp: Time.now.iso8601 },
38
+ sync: true
38
39
  )
39
40
 
40
41
  # Query data
@@ -94,15 +95,19 @@ client.append(
94
95
  ]
95
96
  )
96
97
 
97
- # Override credentials per-request
98
- client.append(
98
+ # Asynchronous append with task polling
99
+ resp = client.append(
99
100
  catalog: "main",
100
101
  schema: "public",
101
102
  table: "events",
102
103
  payload: { user_id: 789 },
103
- username: "other_user",
104
- password: "other_password"
104
+ sync: false
105
105
  )
106
+
107
+ if resp.task_id
108
+ task = client.get_task(resp.task_id)
109
+ puts task.status
110
+ end
106
111
  ```
107
112
 
108
113
  ### `query_all`
@@ -111,7 +116,8 @@ Executes a SQL query and returns all rows in memory (accumulated).
111
116
 
112
117
  ```ruby
113
118
  result = client.query_all(
114
- statement: "SELECT * FROM main.public.events LIMIT 10"
119
+ statement: "SELECT * FROM main.public.events LIMIT 10",
120
+ cache: true
115
121
  )
116
122
 
117
123
  puts result[:metadata] # Hash
@@ -180,6 +186,45 @@ puts resp.valid # => false
180
186
  puts resp.error
181
187
  ```
182
188
 
189
+ ### `get_task`
190
+
191
+ Retrieves the status of an asynchronous append task.
192
+
193
+ ```ruby
194
+ task = client.get_task("task-uuid")
195
+ puts task.status # "pending" or "completed"
196
+ ```
197
+
198
+ ### `explain`
199
+
200
+ Returns scan estimates for a SQL statement without executing it.
201
+
202
+ ```ruby
203
+ resp = client.explain(
204
+ statement: "SELECT * FROM users WHERE age > 25",
205
+ include_plan: true
206
+ )
207
+
208
+ resp.tables.each do |table|
209
+ puts "#{table.table_name}: ~#{table.estimated_rows} rows"
210
+ end
211
+ ```
212
+
213
+ ### `autocomplete`
214
+
215
+ Returns SQL autocomplete suggestions.
216
+
217
+ ```ruby
218
+ resp = client.autocomplete(
219
+ statement: "SEL",
220
+ max_suggestions: 5
221
+ )
222
+
223
+ resp.suggestions.each do |suggestion|
224
+ puts suggestion.suggestion
225
+ end
226
+ ```
227
+
183
228
  ## Configuration
184
229
 
185
230
  | Option | Type | Default | Description |
@@ -0,0 +1,41 @@
1
+ lib = File.expand_path("lib", __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "altertable/lakehouse/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "altertable-lakehouse"
7
+ spec.version = Altertable::Lakehouse::VERSION
8
+ spec.authors = ["Altertable AI"]
9
+ spec.email = ["support@altertable.ai"]
10
+
11
+ spec.summary = "Official Ruby client for Altertable Lakehouse"
12
+ spec.description = "Official Ruby client for Altertable Lakehouse API."
13
+ spec.homepage = "https://github.com/altertable-ai/altertable-lakehouse-ruby"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 3.0.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/altertable-ai/altertable-lakehouse-ruby"
19
+ spec.metadata["changelog_uri"] = "https://github.com/altertable-ai/altertable-lakehouse-ruby/blob/main/CHANGELOG.md"
20
+
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|sorbet)/}) }
23
+ end
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_dependency "base64"
29
+
30
+ spec.add_development_dependency "faraday", "~> 2.12"
31
+ spec.add_development_dependency "faraday-retry", "~> 2.0"
32
+ spec.add_development_dependency "faraday-net_http"
33
+ spec.add_development_dependency "httpx" # For testing optional support
34
+ spec.add_development_dependency "rake", "~> 13.0"
35
+ spec.add_development_dependency "rspec", "~> 3.0"
36
+ spec.add_development_dependency "rubocop", "~> 1.50"
37
+ spec.add_development_dependency "testcontainers"
38
+ spec.add_development_dependency "rbs"
39
+ spec.add_development_dependency "sorbet"
40
+ spec.add_development_dependency "sorbet-runtime"
41
+ end
@@ -43,13 +43,20 @@ module Altertable
43
43
  end
44
44
 
45
45
  # POST /append
46
- def append(catalog:, schema:, table:, payload:)
46
+ def append(catalog:, schema:, table:, payload:, sync: nil)
47
47
  params = { catalog: catalog, schema: schema, table: table }
48
+ params[:sync] = sync unless sync.nil?
48
49
  req = Models::AppendRequest.new(payload)
49
50
  resp = request(:post, "/append", body: req.to_h, query: params)
50
51
  Models::AppendResponse.from_h(resp)
51
52
  end
52
53
 
54
+ # GET /tasks/:task_id
55
+ def get_task(task_id)
56
+ resp = request(:get, "/tasks/#{task_id}")
57
+ Models::TaskResponse.from_h(resp)
58
+ end
59
+
53
60
  # POST /query (streamed)
54
61
  def query(statement:, **options)
55
62
  req_body = Models::QueryRequest.new(statement: statement, **options).to_h.to_json
@@ -109,12 +116,43 @@ module Altertable
109
116
  end
110
117
 
111
118
  # POST /validate
112
- def validate(statement:)
113
- req = Models::ValidateRequest.new(statement: statement)
119
+ def validate(statement:, catalog: nil, schema: nil, session_id: nil)
120
+ req = Models::ValidateRequest.new(
121
+ statement: statement,
122
+ catalog: catalog,
123
+ schema: schema,
124
+ session_id: session_id
125
+ )
114
126
  resp = request(:post, "/validate", body: req.to_h)
115
127
  Models::ValidateResponse.from_h(resp)
116
128
  end
117
129
 
130
+ # POST /autocomplete
131
+ def autocomplete(statement:, catalog: nil, schema: nil, session_id: nil, max_suggestions: nil)
132
+ req = Models::AutocompleteRequest.new(
133
+ statement: statement,
134
+ catalog: catalog,
135
+ schema: schema,
136
+ session_id: session_id,
137
+ max_suggestions: max_suggestions
138
+ )
139
+ resp = request(:post, "/autocomplete", body: req.to_h)
140
+ Models::AutocompleteResponse.from_h(resp)
141
+ end
142
+
143
+ # POST /explain
144
+ def explain(statement:, catalog: nil, schema: nil, session_id: nil, include_plan: nil)
145
+ req = Models::ExplainRequest.new(
146
+ statement: statement,
147
+ catalog: catalog,
148
+ schema: schema,
149
+ session_id: session_id,
150
+ include_plan: include_plan
151
+ )
152
+ resp = request(:post, "/explain", body: req.to_h)
153
+ Models::ExplainResponse.from_h(resp)
154
+ end
155
+
118
156
  private
119
157
 
120
158
  def select_adapter(name, options)
@@ -21,22 +21,42 @@ module Altertable
21
21
  end
22
22
 
23
23
  class AppendResponse < Request
24
- attr_reader :ok, :error_code
24
+ attr_reader :ok, :error_code, :error_message, :task_id
25
25
 
26
- def initialize(ok:, error_code: nil)
26
+ def initialize(ok:, error_code: nil, error_message: nil, task_id: nil)
27
27
  @ok = ok
28
28
  @error_code = error_code
29
+ @error_message = error_message
30
+ @task_id = task_id
29
31
  end
30
32
 
31
33
  def self.from_h(h)
32
- new(ok: h["ok"], error_code: h["error_code"])
34
+ new(
35
+ ok: h["ok"],
36
+ error_code: h["error_code"],
37
+ error_message: h["error_message"],
38
+ task_id: h["task_id"]
39
+ )
40
+ end
41
+ end
42
+
43
+ class TaskResponse < Request
44
+ attr_reader :task_id, :status
45
+
46
+ def initialize(task_id:, status:)
47
+ @task_id = task_id
48
+ @status = status
49
+ end
50
+
51
+ def self.from_h(h)
52
+ new(task_id: h["task_id"], status: h["status"])
33
53
  end
34
54
  end
35
55
 
36
56
  class QueryRequest < Request
37
- attr_reader :statement, :catalog, :schema, :session_id, :compute_size, :sanitize, :limit, :offset, :timezone, :ephemeral, :visible, :requested_by, :query_id
57
+ attr_reader :statement, :catalog, :schema, :session_id, :compute_size, :sanitize, :limit, :offset, :timezone, :ephemeral, :visible, :requested_by, :query_id, :cache
38
58
 
39
- def initialize(statement:, catalog: nil, schema: nil, session_id: nil, compute_size: nil, sanitize: nil, limit: nil, offset: nil, timezone: nil, ephemeral: nil, visible: nil, requested_by: nil, query_id: nil)
59
+ def initialize(statement:, catalog: nil, schema: nil, session_id: nil, compute_size: nil, sanitize: nil, limit: nil, offset: nil, timezone: nil, ephemeral: nil, visible: nil, requested_by: nil, query_id: nil, cache: nil)
40
60
  @statement = statement
41
61
  @catalog = catalog
42
62
  @schema = schema
@@ -50,6 +70,7 @@ module Altertable
50
70
  @visible = visible
51
71
  @requested_by = requested_by
52
72
  @query_id = query_id
73
+ @cache = cache
53
74
  end
54
75
 
55
76
  def to_h
@@ -66,19 +87,27 @@ module Altertable
66
87
  h[:visible] = @visible unless @visible.nil?
67
88
  h[:requested_by] = @requested_by if @requested_by
68
89
  h[:query_id] = @query_id if @query_id
90
+ h[:cache] = @cache unless @cache.nil?
69
91
  h
70
92
  end
71
93
  end
72
94
 
73
95
  class ValidateRequest < Request
74
- attr_reader :statement
96
+ attr_reader :statement, :catalog, :schema, :session_id
75
97
 
76
- def initialize(statement:)
98
+ def initialize(statement:, catalog: nil, schema: nil, session_id: nil)
77
99
  @statement = statement
100
+ @catalog = catalog
101
+ @schema = schema
102
+ @session_id = session_id
78
103
  end
79
104
 
80
105
  def to_h
81
- { statement: @statement }
106
+ h = { statement: @statement }
107
+ h[:catalog] = @catalog if @catalog
108
+ h[:schema] = @schema if @schema
109
+ h[:session_id] = @session_id if @session_id
110
+ h
82
111
  end
83
112
  end
84
113
 
@@ -152,6 +181,149 @@ module Altertable
152
181
  new(cancelled: h["cancelled"], message: h["message"])
153
182
  end
154
183
  end
184
+
185
+ class AutocompleteRequest < Request
186
+ attr_reader :statement, :catalog, :schema, :session_id, :max_suggestions
187
+
188
+ def initialize(statement:, catalog: nil, schema: nil, session_id: nil, max_suggestions: nil)
189
+ @statement = statement
190
+ @catalog = catalog
191
+ @schema = schema
192
+ @session_id = session_id
193
+ @max_suggestions = max_suggestions
194
+ end
195
+
196
+ def to_h
197
+ h = { statement: @statement }
198
+ h[:catalog] = @catalog if @catalog
199
+ h[:schema] = @schema if @schema
200
+ h[:session_id] = @session_id if @session_id
201
+ h[:max_suggestions] = @max_suggestions if @max_suggestions
202
+ h
203
+ end
204
+ end
205
+
206
+ class AutocompleteSuggestion < Request
207
+ attr_reader :suggestion, :suggestion_start, :suggestion_type, :suggestion_score, :extra_char
208
+
209
+ def initialize(suggestion:, suggestion_start:, suggestion_type:, suggestion_score:, extra_char: nil)
210
+ @suggestion = suggestion
211
+ @suggestion_start = suggestion_start
212
+ @suggestion_type = suggestion_type
213
+ @suggestion_score = suggestion_score
214
+ @extra_char = extra_char
215
+ end
216
+
217
+ def self.from_h(h)
218
+ new(
219
+ suggestion: h["suggestion"],
220
+ suggestion_start: h["suggestion_start"],
221
+ suggestion_type: h["suggestion_type"],
222
+ suggestion_score: h["suggestion_score"],
223
+ extra_char: h["extra_char"]
224
+ )
225
+ end
226
+ end
227
+
228
+ class AutocompleteResponse < Request
229
+ attr_reader :suggestions, :statement, :connections_errors
230
+
231
+ def initialize(suggestions:, statement:, connections_errors:)
232
+ @suggestions = suggestions
233
+ @statement = statement
234
+ @connections_errors = connections_errors
235
+ end
236
+
237
+ def self.from_h(h)
238
+ new(
239
+ suggestions: Array(h["suggestions"]).map { |suggestion| AutocompleteSuggestion.from_h(suggestion) },
240
+ statement: h["statement"],
241
+ connections_errors: h["connections_errors"] || {}
242
+ )
243
+ end
244
+ end
245
+
246
+ class ExplainRequest < Request
247
+ attr_reader :statement, :catalog, :schema, :session_id, :include_plan
248
+
249
+ def initialize(statement:, catalog: nil, schema: nil, session_id: nil, include_plan: nil)
250
+ @statement = statement
251
+ @catalog = catalog
252
+ @schema = schema
253
+ @session_id = session_id
254
+ @include_plan = include_plan
255
+ end
256
+
257
+ def to_h
258
+ h = { statement: @statement }
259
+ h[:catalog] = @catalog if @catalog
260
+ h[:schema] = @schema if @schema
261
+ h[:session_id] = @session_id if @session_id
262
+ h[:include_plan] = @include_plan unless @include_plan.nil?
263
+ h
264
+ end
265
+ end
266
+
267
+ class TableScanEstimate < Request
268
+ attr_reader :table_name, :estimated_rows, :filters, :scanned_bytes_estimate,
269
+ :scanned_files_estimate, :total_bytes, :total_files
270
+
271
+ def initialize(table_name:, estimated_rows:, filters: nil, scanned_bytes_estimate: nil,
272
+ scanned_files_estimate: nil, total_bytes: nil, total_files: nil)
273
+ @table_name = table_name
274
+ @estimated_rows = estimated_rows
275
+ @filters = filters
276
+ @scanned_bytes_estimate = scanned_bytes_estimate
277
+ @scanned_files_estimate = scanned_files_estimate
278
+ @total_bytes = total_bytes
279
+ @total_files = total_files
280
+ end
281
+
282
+ def self.from_h(h)
283
+ new(
284
+ table_name: h["table_name"],
285
+ estimated_rows: h["estimated_rows"],
286
+ filters: h["filters"],
287
+ scanned_bytes_estimate: h["scanned_bytes_estimate"],
288
+ scanned_files_estimate: h["scanned_files_estimate"],
289
+ total_bytes: h["total_bytes"],
290
+ total_files: h["total_files"]
291
+ )
292
+ end
293
+ end
294
+
295
+ class ExplainResponse < Request
296
+ attr_reader :tables, :statement, :connections_errors, :error, :plan,
297
+ :scanned_bytes_estimate, :scanned_files_estimate, :total_bytes, :total_files
298
+
299
+ def initialize(tables:, statement:, connections_errors:, error: nil, plan: nil,
300
+ scanned_bytes_estimate: nil, scanned_files_estimate: nil,
301
+ total_bytes: nil, total_files: nil)
302
+ @tables = tables
303
+ @statement = statement
304
+ @connections_errors = connections_errors
305
+ @error = error
306
+ @plan = plan
307
+ @scanned_bytes_estimate = scanned_bytes_estimate
308
+ @scanned_files_estimate = scanned_files_estimate
309
+ @total_bytes = total_bytes
310
+ @total_files = total_files
311
+ end
312
+
313
+ def self.from_h(h)
314
+ new(
315
+ tables: Array(h["tables"]).map { |table| TableScanEstimate.from_h(table) },
316
+ statement: h["statement"],
317
+ connections_errors: h["connections_errors"] || {},
318
+ error: h["error"],
319
+ plan: h["plan"],
320
+ scanned_bytes_estimate: h["scanned_bytes_estimate"],
321
+ scanned_files_estimate: h["scanned_files_estimate"],
322
+ total_bytes: h["total_bytes"],
323
+ total_files: h["total_files"]
324
+ )
325
+ end
326
+ end
155
327
  end
156
328
  end
157
329
  end
@@ -1,5 +1,5 @@
1
1
  module Altertable
2
2
  module Lakehouse
3
- VERSION = "0.3.0"
3
+ VERSION = "0.4.1"
4
4
  end
5
5
  end