trino-client 1.0.0

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.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/PULL_REQUEST_TEMPLATE.md +18 -0
  4. data/.github/workflows/ruby.yml +30 -0
  5. data/.gitignore +4 -0
  6. data/ChangeLog.md +168 -0
  7. data/Gemfile +7 -0
  8. data/LICENSE +202 -0
  9. data/README.md +131 -0
  10. data/Rakefile +45 -0
  11. data/lib/trino-client.rb +1 -0
  12. data/lib/trino/client.rb +23 -0
  13. data/lib/trino/client/client.rb +78 -0
  14. data/lib/trino/client/errors.rb +46 -0
  15. data/lib/trino/client/faraday_client.rb +242 -0
  16. data/lib/trino/client/model_versions/0.149.rb +1683 -0
  17. data/lib/trino/client/model_versions/0.153.rb +1719 -0
  18. data/lib/trino/client/model_versions/0.173.rb +1685 -0
  19. data/lib/trino/client/model_versions/0.178.rb +1964 -0
  20. data/lib/trino/client/model_versions/0.205.rb +2169 -0
  21. data/lib/trino/client/model_versions/303.rb +2574 -0
  22. data/lib/trino/client/model_versions/316.rb +2595 -0
  23. data/lib/trino/client/model_versions/351.rb +2726 -0
  24. data/lib/trino/client/models.rb +38 -0
  25. data/lib/trino/client/query.rb +144 -0
  26. data/lib/trino/client/statement_client.rb +279 -0
  27. data/lib/trino/client/version.rb +20 -0
  28. data/modelgen/model_versions.rb +280 -0
  29. data/modelgen/modelgen.rb +119 -0
  30. data/modelgen/models.rb +31 -0
  31. data/modelgen/trino_models.rb +270 -0
  32. data/release.rb +56 -0
  33. data/spec/basic_query_spec.rb +82 -0
  34. data/spec/client_spec.rb +75 -0
  35. data/spec/gzip_spec.rb +40 -0
  36. data/spec/model_spec.rb +35 -0
  37. data/spec/spec_helper.rb +42 -0
  38. data/spec/statement_client_spec.rb +637 -0
  39. data/spec/tpch/q01.sql +21 -0
  40. data/spec/tpch/q02.sql +43 -0
  41. data/spec/tpch_query_spec.rb +41 -0
  42. data/trino-client.gemspec +31 -0
  43. metadata +211 -0
@@ -0,0 +1,20 @@
1
+ #
2
+ # Trino client for Ruby
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ module Trino
17
+ module Client
18
+ VERSION = "1.0.0"
19
+ end
20
+ end
@@ -0,0 +1,280 @@
1
+ #
2
+ # Trino client for Ruby
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ module Trino::Client::ModelVersions
17
+
18
+ ####
19
+ ## lib/trino/client/model_versions/*.rb is automatically generated using "rake modelgen:all" command.
20
+ ## You should not edit this file directly. To modify the class definitions, edit
21
+ ## modelgen/model_versions.rb file and run "rake modelgen:all".
22
+ ##
23
+
24
+ module V<%= @model_version.gsub(".", "_") %>
25
+ class Base < Struct
26
+ class << self
27
+ alias_method :new_struct, :new
28
+
29
+ def new(*args)
30
+ new_struct(*args) do
31
+ # make it immutable
32
+ undef_method :"[]="
33
+ members.each do |m|
34
+ undef_method :"#{m}="
35
+ end
36
+
37
+ # replace constructor to receive hash instead of array
38
+ alias_method :initialize_struct, :initialize
39
+
40
+ def initialize(params={})
41
+ initialize_struct(*members.map {|m| params[m] })
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ class StageId < String
49
+ def initialize(str)
50
+ super
51
+ splitted = split('.', 2)
52
+ @query_id = splitted[0]
53
+ @id = splitted[1]
54
+ end
55
+
56
+ attr_reader :query_id, :id
57
+ end
58
+
59
+ class TaskId < String
60
+ def initialize(str)
61
+ super
62
+ splitted = split('.', 3)
63
+ @stage_id = StageId.new("#{splitted[0]}.#{splitted[1]}")
64
+ @query_id = @stage_id.query_id
65
+ @id = splitted[2]
66
+ end
67
+
68
+ attr_reader :query_id, :stage_id, :id
69
+ end
70
+
71
+ class Lifespan < String
72
+ def initialize(str)
73
+ super
74
+ if str == "TaskWide"
75
+ @grouped = false
76
+ @group_id = 0
77
+ else
78
+ # Group1
79
+ @grouped = true
80
+ @group_id = str[5..-1].to_i
81
+ end
82
+ end
83
+
84
+ attr_reader :grouped, :group_id
85
+ end
86
+
87
+ class ConnectorSession < Hash
88
+ def initialize(hash)
89
+ super()
90
+ merge!(hash)
91
+ end
92
+ end
93
+
94
+ module PlanNode
95
+ def self.decode(hash)
96
+ unless hash.is_a?(Hash)
97
+ raise TypeError, "Can't convert #{hash.class} to Hash"
98
+ end
99
+ model_class = case hash["@type"]
100
+ when "output" then OutputNode
101
+ when "project" then ProjectNode
102
+ when "tablescan" then TableScanNode
103
+ when "values" then ValuesNode
104
+ when "aggregation" then AggregationNode
105
+ when "markDistinct" then MarkDistinctNode
106
+ when "filter" then FilterNode
107
+ when "window" then WindowNode
108
+ when "rowNumber" then RowNumberNode
109
+ when "topnRowNumber" then TopNRowNumberNode
110
+ when "limit" then LimitNode
111
+ when "distinctlimit" then DistinctLimitNode
112
+ when "topn" then TopNNode
113
+ when "sample" then SampleNode
114
+ when "sort" then SortNode
115
+ when "remoteSource" then RemoteSourceNode
116
+ when "join" then JoinNode
117
+ when "semijoin" then SemiJoinNode
118
+ when "spatialjoin" then SpatialJoinNode
119
+ when "indexjoin" then IndexJoinNode
120
+ when "indexsource" then IndexSourceNode
121
+ when "tablewriter" then TableWriterNode
122
+ when "delete" then DeleteNode
123
+ when "metadatadelete" then MetadataDeleteNode
124
+ when "tablecommit" then TableFinishNode
125
+ when "unnest" then UnnestNode
126
+ when "exchange" then ExchangeNode
127
+ when "union" then UnionNode
128
+ when "intersect" then IntersectNode
129
+ when "scalar" then EnforceSingleRowNode
130
+ when "groupid" then GroupIdNode
131
+ when "explainAnalyze" then ExplainAnalyzeNode
132
+ when "apply" then ApplyNode
133
+ when "assignUniqueId" then AssignUniqueId
134
+ when "correlatedJoin" then CorrelatedJoinNode
135
+ when "statisticsWriterNode" then StatisticsWriterNode
136
+ end
137
+ if model_class
138
+ node = model_class.decode(hash)
139
+ class << node
140
+ attr_accessor :plan_node_type
141
+ end
142
+ node.plan_node_type = hash['@type']
143
+ node
144
+ end
145
+ end
146
+ end
147
+
148
+ # io.airlift.stats.Distribution.DistributionSnapshot
149
+ class << DistributionSnapshot =
150
+ Base.new(:max_error, :count, :total, :p01, :p05, :p10, :p25, :p50, :p75, :p90, :p95, :p99, :min, :max)
151
+ def decode(hash)
152
+ unless hash.is_a?(Hash)
153
+ raise TypeError, "Can't convert #{hash.class} to Hash"
154
+ end
155
+ obj = allocate
156
+ obj.send(:initialize_struct,
157
+ hash["maxError"],
158
+ hash["count"],
159
+ hash["total"],
160
+ hash["p01"],
161
+ hash["p05"],
162
+ hash["p10"],
163
+ hash["p25"],
164
+ hash["p50"],
165
+ hash["p75"],
166
+ hash["p90"],
167
+ hash["p95"],
168
+ hash["p99"],
169
+ hash["min"],
170
+ hash["max"],
171
+ )
172
+ obj
173
+ end
174
+ end
175
+
176
+ # This is a hybrid of JoinNode.EquiJoinClause and IndexJoinNode.EquiJoinClause
177
+ class << EquiJoinClause =
178
+ Base.new(:left, :right, :probe, :index)
179
+ def decode(hash)
180
+ unless hash.is_a?(Hash)
181
+ raise TypeError, "Can't convert #{hash.class} to Hash"
182
+ end
183
+ obj = allocate
184
+ obj.send(:initialize_struct,
185
+ hash["left"],
186
+ hash["right"],
187
+ hash["probe"],
188
+ hash["index"],
189
+ )
190
+ obj
191
+ end
192
+ end
193
+
194
+ class << WriterTarget =
195
+ Base.new(:type, :handle)
196
+ def decode(hash)
197
+ unless hash.is_a?(Hash)
198
+ raise TypeError, "Can't convert #{hash.class} to Hash"
199
+ end
200
+ obj = allocate
201
+ model_class = case hash["@type"]
202
+ when "CreateTarget" then CreateTarget
203
+ when "InsertTarget" then InsertTarget
204
+ when "DeleteTarget" then DeleteTarget
205
+ end
206
+ if model_class
207
+ model_class.decode(hash)
208
+ end
209
+ end
210
+ end
211
+
212
+ class << WriteStatisticsTarget =
213
+ Base.new(:type, :handle)
214
+ def decode(hash)
215
+ unless hash.is_a?(Hash)
216
+ raise TypeError, "Can't convert #{hash.class} to Hash"
217
+ end
218
+ obj = allocate
219
+ model_class = case hash["@type"]
220
+ when "WriteStatisticsHandle" then WriteStatisticsHandle
221
+ end
222
+ if model_class
223
+ model_class.decode(hash)
224
+ end
225
+ end
226
+ end
227
+
228
+ # Inner classes
229
+ module OperatorInfo
230
+ def self.decode(hash)
231
+ unless hash.is_a?(Hash)
232
+ raise TypeError, "Can't convert #{hash.class} to Hash"
233
+ end
234
+ model_class = case hash["@type"]
235
+ when "exchangeClientStatus" then ExchangeClientStatus
236
+ when "localExchangeBuffer" then LocalExchangeBufferInfo
237
+ when "tableFinish" then TableFinishInfo
238
+ when "splitOperator" then SplitOperatorInfo
239
+ when "hashCollisionsInfo" then HashCollisionsInfo
240
+ when "partitionedOutput" then PartitionedOutputInfo
241
+ when "joinOperatorInfo" then JoinOperatorInfo
242
+ when "windowInfo" then WindowInfo
243
+ when "tableWriter" then TableWriterInfo
244
+ end
245
+ if model_class
246
+ model_class.decode(hash)
247
+ end
248
+ end
249
+ end
250
+
251
+ class << HashCollisionsInfo =
252
+ Base.new(:weighted_hash_collisions, :weighted_sum_squared_hash_collisions, :weighted_expectedHash_collisions)
253
+ def decode(hash)
254
+ unless hash.is_a?(Hash)
255
+ raise TypeError, "Can't convert #{hash.class} to Hash"
256
+ end
257
+ obj = allocate
258
+ obj.send(:initialize_struct,
259
+ hash["weighted_hash_collisions"],
260
+ hash["weighted_sum_squared_hash_collisions"],
261
+ hash["weighted_expectedHash_collisions"]
262
+ )
263
+ obj
264
+ end
265
+ end
266
+
267
+ class ResourceGroupId < Array
268
+ def initialize(array)
269
+ super()
270
+ concat(array)
271
+ end
272
+ end
273
+
274
+ ##
275
+ # Those model classes are automatically generated
276
+ #
277
+
278
+ <%= @contents %>
279
+ end
280
+ end
@@ -0,0 +1,119 @@
1
+
2
+ if ARGV.length != 4
3
+ puts "usage: <model-version> <trino-source-dir> <template.erb> <output.rb>"
4
+ exit 1
5
+ end
6
+
7
+ model_version, source_dir, template_path, output_path = *ARGV
8
+
9
+ require_relative 'trino_models'
10
+
11
+ require 'erb'
12
+ erb = ERB.new(File.read(template_path))
13
+
14
+ source_path = source_dir
15
+
16
+ predefined_simple_classes = %w[StageId TaskId Lifespan ConnectorSession ResourceGroupId]
17
+ predefined_models = %w[DistributionSnapshot PlanNode EquiJoinClause WriterTarget WriteStatisticsTarget OperatorInfo HashCollisionsInfo]
18
+
19
+ assume_primitive = %w[Object Type Long Symbol QueryId PlanNodeId PlanFragmentId MemoryPoolId TransactionId URI Duration DataSize DateTime ColumnHandle ConnectorTableHandle ConnectorOutputTableHandle ConnectorIndexHandle ConnectorColumnHandle ConnectorInsertTableHandle ConnectorTableLayoutHandle Expression FunctionCall TimeZoneKey Locale TypeSignature Frame TupleDomain<ColumnHandle> SerializableNativeValue ConnectorTransactionHandle OutputBufferId ConnectorPartitioningHandle NullableValue ConnectorId HostAddress JsonNode Node CatalogName QualifiedObjectName FunctionId DynamicFilterId Instant]
20
+ enum_types = %w[QueryState StageState TaskState QueueState PlanDistribution OutputPartitioning Step SortOrder BufferState NullPartitioning BlockedReason ParameterKind FunctionKind PartitionFunctionHandle Scope ErrorType DistributionType PipelineExecutionStrategy JoinType ExchangeNode.Type ColumnStatisticType TableStatisticType StageExecutionStrategy SemanticErrorCode QueryType]
21
+
22
+ root_models = %w[QueryResults QueryInfo BasicQueryInfo] + %w[
23
+ OutputNode
24
+ ProjectNode
25
+ TableScanNode
26
+ ValuesNode
27
+ AggregationNode
28
+ MarkDistinctNode
29
+ FilterNode
30
+ WindowNode
31
+ RowNumberNode
32
+ TopNRowNumberNode
33
+ LimitNode
34
+ DistinctLimitNode
35
+ TopNNode
36
+ SampleNode
37
+ SortNode
38
+ RemoteSourceNode
39
+ JoinNode
40
+ SemiJoinNode
41
+ SpatialJoinNode
42
+ IndexJoinNode
43
+ IndexSourceNode
44
+ TableWriterNode
45
+ DeleteNode
46
+ TableFinishNode
47
+ UnnestNode
48
+ ExchangeNode
49
+ UnionNode
50
+ IntersectNode
51
+ EnforceSingleRowNode
52
+ GroupIdNode
53
+ ExplainAnalyzeNode
54
+ ApplyNode
55
+ AssignUniqueId
56
+ CorrelatedJoinNode
57
+ StatisticsWriterNode
58
+ ] + %w[
59
+ ExchangeClientStatus
60
+ LocalExchangeBufferInfo
61
+ TableFinishInfo
62
+ SplitOperatorInfo
63
+ PartitionedOutputInfo
64
+ JoinOperatorInfo
65
+ WindowInfo
66
+ TableWriterInfo
67
+ ]
68
+
69
+ name_mapping = Hash[*%w[
70
+ StatementStats StageStats ClientStageStats
71
+ ClientStageStats StageStats ClientStageStats
72
+ QueryResults Column ClientColumn
73
+ ].each_slice(3).map { |x, y, z| [[x,y], z] }.flatten(1)]
74
+
75
+ path_mapping = Hash[*%w[
76
+ ClientColumn client/trino-client/src/main/java/io/trino/client/Column.java
77
+ ClientStageStats client/trino-client/src/main/java/io/trino/client/StageStats.java
78
+ Column core/trino-main/src/main/java/io/trino/execution/Column.java
79
+ QueryStats core/trino-main/src/main/java/io/trino/execution/QueryStats.java
80
+ StageStats core/trino-main/src/main/java/io/trino/execution/StageStats.java
81
+ PartitionedOutputInfo core/trino-main/src/main/java/io/trino/operator/PartitionedOutputOperator.java
82
+ TableWriterInfo core/trino-main/src/main/java/io/trino/operator/TableWriterOperator.java
83
+ TableInfo core/trino-main/src/main/java/io/trino/execution/TableInfo.java
84
+ DynamicFiltersStats core/trino-main/src/main/java/io/trino/server/DynamicFilterService.java
85
+ ].map.with_index { |v,i| i % 2 == 0 ? v : (source_path + "/" + v) }]
86
+
87
+ # model => [ [key,nullable,type], ... ]
88
+ extra_fields = {
89
+ 'QueryInfo' => [['finalQueryInfo', nil, 'boolean']]
90
+ }
91
+
92
+ analyzer = TrinoModels::ModelAnalyzer.new(
93
+ source_path,
94
+ skip_models: predefined_models + predefined_simple_classes + assume_primitive + enum_types,
95
+ path_mapping: path_mapping,
96
+ name_mapping: name_mapping,
97
+ extra_fields: extra_fields
98
+ )
99
+ analyzer.analyze(root_models)
100
+ models = analyzer.models
101
+ skipped_models = analyzer.skipped_models
102
+
103
+ formatter = TrinoModels::ModelFormatter.new(
104
+ base_indent_count: 2,
105
+ struct_class: "Base",
106
+ special_struct_initialize_method: "initialize_struct",
107
+ primitive_types: assume_primitive,
108
+ skip_types: skipped_models,
109
+ simple_classes: predefined_simple_classes,
110
+ enum_types: enum_types,
111
+ )
112
+ formatter.format(models)
113
+
114
+ @contents = formatter.contents
115
+ @model_version = model_version
116
+
117
+ data = erb.result
118
+ File.write(output_path, data)
119
+
@@ -0,0 +1,31 @@
1
+ #
2
+ # Trino client for Ruby
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ module Trino::Client
17
+
18
+ ####
19
+ ## lib/trino/client/models.rb is automatically generated using "rake modelgen:latest" command.
20
+ ## You should not edit this file directly. To modify the class definitions, edit
21
+ ## modelgen/models.rb file and run "rake modelgen:latest".
22
+ ##
23
+
24
+ module ModelVersions
25
+ end
26
+ <% @versions.each do |ver| %>
27
+ require 'trino/client/model_versions/<%= ver %>.rb'<% end %>
28
+
29
+ Models = ModelVersions::V<%= @latest_version.gsub(".", "_") %>
30
+
31
+ end