trino-client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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