elasticgraph-graphql 1.0.2 → 1.0.3.rc1

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 (79) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/lib/elastic_graph/graphql/aggregation/composite_grouping_adapter.rb +1 -1
  4. data/lib/elastic_graph/graphql/aggregation/computation.rb +1 -1
  5. data/lib/elastic_graph/graphql/aggregation/date_histogram_grouping.rb +5 -1
  6. data/lib/elastic_graph/graphql/aggregation/field_path_encoder.rb +1 -1
  7. data/lib/elastic_graph/graphql/aggregation/field_term_grouping.rb +22 -2
  8. data/lib/elastic_graph/graphql/aggregation/key.rb +1 -1
  9. data/lib/elastic_graph/graphql/aggregation/nested_sub_aggregation.rb +1 -1
  10. data/lib/elastic_graph/graphql/aggregation/non_composite_grouping_adapter.rb +17 -8
  11. data/lib/elastic_graph/graphql/aggregation/path_segment.rb +1 -1
  12. data/lib/elastic_graph/graphql/aggregation/query.rb +25 -22
  13. data/lib/elastic_graph/graphql/aggregation/query_adapter.rb +3 -2
  14. data/lib/elastic_graph/graphql/aggregation/query_optimizer.rb +1 -1
  15. data/lib/elastic_graph/graphql/aggregation/resolvers/aggregated_values.rb +1 -1
  16. data/lib/elastic_graph/graphql/aggregation/resolvers/count_detail.rb +1 -1
  17. data/lib/elastic_graph/graphql/aggregation/resolvers/grouped_by.rb +1 -1
  18. data/lib/elastic_graph/graphql/aggregation/resolvers/node.rb +1 -1
  19. data/lib/elastic_graph/graphql/aggregation/resolvers/relay_connection_builder.rb +1 -1
  20. data/lib/elastic_graph/graphql/aggregation/resolvers/sub_aggregations.rb +1 -1
  21. data/lib/elastic_graph/graphql/aggregation/script_term_grouping.rb +5 -1
  22. data/lib/elastic_graph/graphql/aggregation/term_grouping.rb +1 -1
  23. data/lib/elastic_graph/graphql/client.rb +1 -1
  24. data/lib/elastic_graph/graphql/config.rb +1 -1
  25. data/lib/elastic_graph/graphql/datastore_query/document_paginator.rb +1 -1
  26. data/lib/elastic_graph/graphql/datastore_query/index_expression_builder.rb +1 -1
  27. data/lib/elastic_graph/graphql/datastore_query/paginator.rb +1 -1
  28. data/lib/elastic_graph/graphql/datastore_query/routing_picker.rb +1 -1
  29. data/lib/elastic_graph/graphql/datastore_query.rb +1 -1
  30. data/lib/elastic_graph/graphql/datastore_response/document.rb +1 -1
  31. data/lib/elastic_graph/graphql/datastore_response/search_response.rb +1 -1
  32. data/lib/elastic_graph/graphql/datastore_search_router.rb +1 -1
  33. data/lib/elastic_graph/graphql/decoded_cursor.rb +2 -2
  34. data/lib/elastic_graph/graphql/filtering/boolean_query.rb +1 -1
  35. data/lib/elastic_graph/graphql/filtering/field_path.rb +1 -1
  36. data/lib/elastic_graph/graphql/filtering/filter_args_translator.rb +1 -1
  37. data/lib/elastic_graph/graphql/filtering/filter_interpreter.rb +1 -1
  38. data/lib/elastic_graph/graphql/filtering/filter_node_interpreter.rb +1 -1
  39. data/lib/elastic_graph/graphql/filtering/filter_value_set_extractor.rb +1 -1
  40. data/lib/elastic_graph/graphql/filtering/range_query.rb +39 -5
  41. data/lib/elastic_graph/graphql/http_endpoint.rb +1 -1
  42. data/lib/elastic_graph/graphql/query_adapter/filters.rb +1 -1
  43. data/lib/elastic_graph/graphql/query_adapter/pagination.rb +1 -1
  44. data/lib/elastic_graph/graphql/query_adapter/requested_fields.rb +1 -1
  45. data/lib/elastic_graph/graphql/query_adapter/sort.rb +1 -1
  46. data/lib/elastic_graph/graphql/query_details_tracker.rb +10 -1
  47. data/lib/elastic_graph/graphql/query_executor.rb +6 -6
  48. data/lib/elastic_graph/graphql/resolvers/get_record_field_value.rb +1 -1
  49. data/lib/elastic_graph/graphql/resolvers/graphql_adapter_builder.rb +1 -1
  50. data/lib/elastic_graph/graphql/resolvers/list_records.rb +1 -1
  51. data/lib/elastic_graph/graphql/resolvers/nested_relationships.rb +1 -1
  52. data/lib/elastic_graph/graphql/resolvers/nested_relationships_source.rb +1 -1
  53. data/lib/elastic_graph/graphql/resolvers/object.rb +1 -1
  54. data/lib/elastic_graph/graphql/resolvers/query_adapter.rb +1 -1
  55. data/lib/elastic_graph/graphql/resolvers/query_source.rb +1 -1
  56. data/lib/elastic_graph/graphql/resolvers/relay_connection/array_adapter.rb +1 -1
  57. data/lib/elastic_graph/graphql/resolvers/relay_connection/generic_adapter.rb +1 -1
  58. data/lib/elastic_graph/graphql/resolvers/relay_connection/page_info.rb +1 -1
  59. data/lib/elastic_graph/graphql/resolvers/relay_connection/search_response_adapter_builder.rb +1 -1
  60. data/lib/elastic_graph/graphql/resolvers/relay_connection.rb +1 -1
  61. data/lib/elastic_graph/graphql/resolvers/resolvable_value.rb +1 -1
  62. data/lib/elastic_graph/graphql/scalar_coercion_adapters/cursor.rb +1 -1
  63. data/lib/elastic_graph/graphql/scalar_coercion_adapters/date.rb +1 -1
  64. data/lib/elastic_graph/graphql/scalar_coercion_adapters/date_time.rb +5 -6
  65. data/lib/elastic_graph/graphql/scalar_coercion_adapters/local_time.rb +1 -1
  66. data/lib/elastic_graph/graphql/scalar_coercion_adapters/longs.rb +1 -1
  67. data/lib/elastic_graph/graphql/scalar_coercion_adapters/no_op.rb +1 -1
  68. data/lib/elastic_graph/graphql/scalar_coercion_adapters/time_zone.rb +1 -1
  69. data/lib/elastic_graph/graphql/scalar_coercion_adapters/untyped.rb +1 -1
  70. data/lib/elastic_graph/graphql/scalar_coercion_adapters/valid_time_zones.rb +1 -1
  71. data/lib/elastic_graph/graphql/schema/arguments.rb +1 -1
  72. data/lib/elastic_graph/graphql/schema/enum_value.rb +1 -1
  73. data/lib/elastic_graph/graphql/schema/field.rb +1 -1
  74. data/lib/elastic_graph/graphql/schema/relation_join.rb +1 -1
  75. data/lib/elastic_graph/graphql/schema/type.rb +24 -1
  76. data/lib/elastic_graph/graphql/schema.rb +2 -1
  77. data/lib/elastic_graph/graphql.rb +1 -1
  78. data/script/dump_time_zones +1 -1
  79. metadata +24 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0ddbc4f495bfbdd561f8bd06c8f8335a6a4f34595442079f2d3334b81ff41e33
4
- data.tar.gz: 8dc723137bf6f4a797c1730328998590edb5f18e320508c63230318912319bff
3
+ metadata.gz: 491f97b51a739a57f7fd24238518fc02c0642ba2536da338d287694025f1cc9a
4
+ data.tar.gz: ed33c16391844f8b3321ec5849dba8a7acbe502ace6286aaabc401122d085aee
5
5
  SHA512:
6
- metadata.gz: b51d3a76bb336ff1515381b15d1c96b9aaaf983627991083b93cd709d075b8e23c15f4992e712e4392e4b7627fad05b20802135e7373550265f59cdda3132bf4
7
- data.tar.gz: 2442920912c9351603f69035ade684316dbda364295d0ba8d8c7450e5929c77da273501a110ebab7e2e39ecdb6f9296eaddad36afc13f694c8a76d379fd93098
6
+ metadata.gz: 4608f68a96a8f3f55af27ca0102552888f391243c2d71961a0e395f3b9c66ea0d4fde3b68933e04d974243c4ef10c8282ff377f5888e5c1de799f4660a6b15d8
7
+ data.tar.gz: 9c3e3ea42f82d421c5319c373f60f23666bee9237ed7df0e84ea2a51f0d7228af49bbc8e3cce9856eaac532b5ea0b0110e7afb9204abd9e737e055743425bb9e
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2024 - 2025 Block, Inc.
3
+ Copyright (c) 2024 - 2026 Block, Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -53,6 +53,10 @@ module ElasticGraph
53
53
  INNER_META
54
54
  end
55
55
 
56
+ def handles_missing_values?
57
+ false
58
+ end
59
+
56
60
  INNER_META = {
57
61
  # On a date histogram aggregation, the `key` is formatted as a number (milliseconds since epoch). We
58
62
  # need it formatted as a string, which `key_as_string` provides.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -11,10 +11,30 @@ require "elastic_graph/graphql/aggregation/term_grouping"
11
11
  module ElasticGraph
12
12
  class GraphQL
13
13
  module Aggregation
14
- class FieldTermGrouping < Support::MemoizableData.define(:field_path)
14
+ class FieldTermGrouping < Support::MemoizableData.define(:field_path, :missing_value_placeholder)
15
15
  # @dynamic field_path
16
16
  include TermGrouping
17
17
 
18
+ # Returns true if this grouping handles missing values using a placeholder value
19
+ # instead of a separate missing aggregation.
20
+ #
21
+ # @return [Boolean] true if missing values are handled via placeholder
22
+ def handles_missing_values?
23
+ !missing_value_placeholder.nil?
24
+ end
25
+
26
+ def non_composite_clause_for(query)
27
+ return super unless handles_missing_values?
28
+
29
+ Support::HashUtil.deep_merge(super, {"terms" => {"missing" => missing_value_placeholder}})
30
+ end
31
+
32
+ def inner_meta
33
+ return super unless handles_missing_values?
34
+
35
+ super.merge({"missing_values" => [missing_value_placeholder]})
36
+ end
37
+
18
38
  private
19
39
 
20
40
  def terms_subclause
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -65,29 +65,38 @@ module ElasticGraph
65
65
  def format_buckets(sub_agg, buckets_path, parent_key_fields: {}, parent_key_values: [])
66
66
  agg_with_buckets = sub_agg.dig(*buckets_path)
67
67
 
68
- missing_bucket = {
69
- # Doc counts in missing value buckets are always perfectly accurate.
70
- "doc_count_error_upper_bound" => 0
71
- }.merge(sub_agg.dig(*missing_bucket_path_from(buckets_path))) # : ::Hash[::String, untyped]
72
-
73
68
  meta = agg_with_buckets.fetch("meta")
74
69
 
75
70
  grouping_field_names = meta.fetch("grouping_fields") # provides the names of the fields being grouped on
76
71
  key_path = meta.fetch("key_path") # indicates whether we want to get the key values from `key` or `key_as_string`.
77
72
  sub_buckets_path = meta["buckets_path"] # buckets_path is optional, so we don't use fetch.
73
+ missing_values = meta["missing_values"] # missing_values is optional, so we don't use fetch.
78
74
  merge_into_bucket = meta.fetch("merge_into_bucket")
79
75
 
80
76
  raw_buckets = agg_with_buckets.fetch("buckets") # : ::Array[::Hash[::String, untyped]]
81
77
 
82
78
  # If the missing bucket is non-empty, include it. This matches the behavior of composite aggregations
83
79
  # when the `missing_bucket` option is used.
84
- raw_buckets += [missing_bucket] if missing_bucket.fetch("doc_count") > 0
80
+ missing_bucket = sub_agg.dig(*missing_bucket_path_from(buckets_path)) || {}
81
+ if missing_bucket.fetch("doc_count", 0) > 0
82
+ # Doc counts in missing value buckets are always perfectly accurate.
83
+ raw_buckets += [{"doc_count_error_upper_bound" => 0}.merge(missing_bucket)]
84
+ end
85
85
 
86
86
  raw_buckets.flat_map do |raw_bucket|
87
+ key_values = Array(raw_bucket.dig(*key_path))
88
+ if missing_values
89
+ # if missing_values are present, then for each element in key_values, replace with nil if it matches the placeholder value from missing_values
90
+ key_values = key_values.each_with_index.map do |value, index|
91
+ # @type var value: untyped
92
+ # @type var index: Integer
93
+ (value == missing_values[index]) ? nil : value
94
+ end
95
+ end
96
+
87
97
  # The key will either be a single value (e.g. `47`) if we used a `terms`/`date_histogram` aggregation,
88
98
  # or a tuple of values (e.g. `[47, "abc"]`) if we used a `multi_terms` aggregation. Here we convert it
89
99
  # to the form needed for resolving `grouped_by` fields: a hash like `{"size" => 47, "tag" => "abc"}`.
90
- key_values = Array(raw_bucket.dig(*key_path))
91
100
  key_fields_hash = grouping_field_names.zip(key_values).to_h
92
101
 
93
102
  # If we have multiple levels of aggregations, we need to merge the key fields hash with the key fields from the parent levels.
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -154,27 +154,30 @@ module ElasticGraph
154
154
  "meta" => meta.merge(extra_inner_meta)
155
155
  }.compact
156
156
 
157
- missing_bucket_inner_agg_hash = inner_agg_hash.key?("aggs") ? inner_agg_hash : {} # : ::Hash[::String, untyped]
158
-
159
- AggregationDetail.new(
160
- {
161
- agg_key => grouping.non_composite_clause_for(query).merge(inner_agg_hash),
162
-
163
- # Here we include a `missing` aggregation as a sibling to the main grouping aggregation. We do this
164
- # so that we get a bucket of documents that have `null` values for the field we are grouping on, in
165
- # order to provide the same behavior as the `CompositeGroupingAdapter` (which uses the built-in
166
- # `missing_bucket` option).
167
- #
168
- # To work correctly, we need to include this `missing` aggregation as a sibling at _every_ level of
169
- # the aggregation structure, and the `missing` aggregation needs the same child aggregations as the
170
- # main grouping aggregation has. Given the recursive nature of how this is applied, this results in
171
- # a fairly complex structure, even though conceptually the idea behind this isn't _too_ bad.
172
- Key.missing_value_bucket_key(agg_key) => {
173
- "missing" => {"field" => grouping.encoded_index_field_path}
174
- }.merge(missing_bucket_inner_agg_hash)
175
- },
176
- {"buckets_path" => [agg_key]}
177
- )
157
+ wrapped_clauses = {
158
+ agg_key => grouping.non_composite_clause_for(query).merge(inner_agg_hash)
159
+ }
160
+
161
+ unless grouping.handles_missing_values?
162
+ # Here we include a `missing` aggregation as a sibling to the main grouping aggregation. We do this
163
+ # so that we get a bucket of documents that have `null` values for the field we are grouping on, in
164
+ # order to provide the same behavior as the `CompositeGroupingAdapter` (which uses the built-in
165
+ # `missing_bucket` option).
166
+ #
167
+ # To work correctly, we need to include this `missing` aggregation as a sibling at _every_ level of
168
+ # the aggregation structure, and the `missing` aggregation needs the same child aggregations as the
169
+ # main grouping aggregation has. Given the recursive nature of how this is applied, this results in
170
+ # a fairly complex structure, even though conceptually the idea behind this isn't _too_ bad.
171
+ missing_bucket_inner_agg_hash = inner_agg_hash.key?("aggs") ? inner_agg_hash : {} # : ::Hash[::String, untyped]
172
+ missing_bucket_inner_agg_hash = missing_bucket_inner_agg_hash.merge({
173
+ "missing" => {"field" => grouping.encoded_index_field_path}
174
+ })
175
+ wrapped_clauses = wrapped_clauses.merge({
176
+ Key.missing_value_bucket_key(agg_key) => missing_bucket_inner_agg_hash
177
+ })
178
+ end
179
+
180
+ AggregationDetail.new(wrapped_clauses, {"buckets_path" => [agg_key]})
178
181
  end
179
182
  end
180
183
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -211,7 +211,8 @@ module ElasticGraph
211
211
  date_time_groupings_from(field_path: field_path, node: node)
212
212
  elsif !field.type.object?
213
213
  # Non-date/time grouping
214
- [FieldTermGrouping.new(field_path: field_path)]
214
+ missing_value_placeholder = field.type.unwrap_fully.grouping_missing_value_placeholder
215
+ [FieldTermGrouping.new(field_path: field_path, missing_value_placeholder: missing_value_placeholder)]
215
216
  end
216
217
  end
217
218
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -16,6 +16,10 @@ module ElasticGraph
16
16
  # @dynamic field_path
17
17
  include TermGrouping
18
18
 
19
+ def handles_missing_values?
20
+ false
21
+ end
22
+
19
23
  private
20
24
 
21
25
  def terms_subclause
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -55,7 +55,7 @@ module ElasticGraph
55
55
  # Encodes the cursor to a string using JSON and Base64 encoding.
56
56
  def encode
57
57
  @encode ||= begin
58
- json = ::JSON.fast_generate(sort_values)
58
+ json = ::JSON.generate(sort_values)
59
59
  ::Base64.urlsafe_encode64(json, padding: false)
60
60
  end
61
61
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -39,15 +39,49 @@ module ElasticGraph
39
39
  # a value > 10 and a value < 100 (even though no single value satisfies both parts!). When we combine
40
40
  # the clauses into a single `range` query then the filtering works like we expect.
41
41
  class RangeQuery < ::Data.define(:field_name, :operator, :value)
42
+ SAME_TYPE_OPS = {
43
+ gt: [:gt, :gte],
44
+ gte: [:gt, :gte],
45
+ lt: [:lt, :lte],
46
+ lte: [:lt, :lte]
47
+ }.freeze
48
+
42
49
  def merge_into(bool_node)
43
50
  existing_range_index = bool_node[:filter].find_index { |clause| clause.dig(:range, field_name) }
44
- new_range_clause = {range: {field_name => {operator => value}}}
45
51
 
46
52
  if existing_range_index
47
- existing_range_clause = bool_node[:filter][existing_range_index]
48
- bool_node[:filter][existing_range_index] = Support::HashUtil.deep_merge(existing_range_clause, new_range_clause)
53
+ existing_range_hash = bool_node[:filter][existing_range_index].dig(:range, field_name)
54
+ merged_range_hash = merge_operators(existing_range_hash)
55
+ bool_node[:filter][existing_range_index] = {range: {field_name => merged_range_hash}}
56
+ else
57
+ bool_node[:filter] << {range: {field_name => {operator => value}}}
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ # Merges the new operator with existing operators.
64
+ # Keeps the stricter one (gt vs gte or lt vs lte) when there are conflicts.
65
+ def merge_operators(existing_range_hash)
66
+ conflicting_op = SAME_TYPE_OPS.fetch(operator).find { |op| existing_range_hash.key?(op) }
67
+
68
+ if conflicting_op
69
+ existing_val = existing_range_hash[conflicting_op]
70
+ stricter_op, stricter_val = stricter_operator(operator, value, conflicting_op, existing_val)
71
+ existing_range_hash.except(conflicting_op).merge(stricter_op => stricter_val)
72
+ else
73
+ existing_range_hash.merge(operator => value)
74
+ end
75
+ end
76
+
77
+ # Returns the stricter of two operators/values in the same direction.
78
+ def stricter_operator(op1, val1, op2, val2)
79
+ if [:gt, :gte].include?(op1)
80
+ # lower bound: higher is stricter, gt wins ties
81
+ (val1 > val2 || (val1 == val2 && op1 == :gt)) ? [op1, val1] : [op2, val2]
49
82
  else
50
- bool_node[:filter] << new_range_clause
83
+ # upper bound: lower is stricter; lt wins ties
84
+ (val1 < val2 || (val1 == val2 && op1 == :lt)) ? [op1, val1] : [op2, val2]
51
85
  end
52
86
  end
53
87
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -17,6 +17,7 @@ module ElasticGraph
17
17
  :datastore_query_server_duration_ms,
18
18
  :datastore_query_client_duration_ms,
19
19
  :queried_shard_count,
20
+ :extension_data,
20
21
  :mutex
21
22
  )
22
23
  def self.empty
@@ -27,6 +28,7 @@ module ElasticGraph
27
28
  datastore_query_server_duration_ms: 0,
28
29
  datastore_query_client_duration_ms: 0,
29
30
  queried_shard_count: 0,
31
+ extension_data: {},
30
32
  mutex: ::Thread::Mutex.new
31
33
  )
32
34
  end
@@ -52,6 +54,13 @@ module ElasticGraph
52
54
  def datastore_request_transport_duration_ms
53
55
  datastore_query_client_duration_ms - datastore_query_server_duration_ms
54
56
  end
57
+
58
+ # Allows extensions to set custom data that will be included in the query duration log.
59
+ def []=(key, value)
60
+ mutex.synchronize do
61
+ extension_data[key] = value
62
+ end
63
+ end
55
64
  end
56
65
  end
57
66
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -65,7 +65,7 @@ module ElasticGraph
65
65
 
66
66
  unless result.to_h.fetch("errors", []).empty?
67
67
  @logger.error <<~EOS
68
- Query #{query.operation_name}[1] for client #{client.description} resulted in errors[2].
68
+ Query #{query.selected_operation_name}[1] for client #{client.description} resulted in errors[2].
69
69
 
70
70
  [1] #{full_description_of(query)}
71
71
 
@@ -79,7 +79,7 @@ module ElasticGraph
79
79
  # returns `nil` on an invalid query, and I don't want to risk leaking PII by logging the raw query string, so
80
80
  # we don't log any form of the query in that case.
81
81
  if duration > @slow_query_threshold_ms
82
- @logger.warn "Query #{query.operation_name} for client #{client.description} with shard routing values " \
82
+ @logger.warn "Query #{query.selected_operation_name} for client #{client.description} with shard routing values " \
83
83
  "#{query_tracker.shard_routing_values.sort.inspect} and search index expressions #{query_tracker.search_index_expressions.sort.inspect} took longer " \
84
84
  "(#{duration} ms) than the configured slow query threshold (#{@slow_query_threshold_ms} ms). " \
85
85
  "Sanitized query:\n\n#{query.sanitized_query_string}"
@@ -90,7 +90,7 @@ module ElasticGraph
90
90
  "message_type" => "ElasticGraphQueryExecutorQueryDuration",
91
91
  "client" => client.name,
92
92
  "query_fingerprint" => fingerprint_for(query),
93
- "query_name" => query.operation_name,
93
+ "query_name" => query.selected_operation_name,
94
94
  "duration_ms" => duration,
95
95
  # How long the datastore queries took according to what the datastore itself reported.
96
96
  "datastore_server_duration_ms" => query_tracker.datastore_query_server_duration_ms,
@@ -117,7 +117,7 @@ module ElasticGraph
117
117
  "datastore_query_count" => query_tracker.query_counts_per_datastore_request.sum,
118
118
  "over_slow_threshold" => (duration > @slow_query_threshold_ms).to_s,
119
119
  "slo_result" => slo_result_for(query, duration)
120
- })
120
+ }.merge(query_tracker.extension_data))
121
121
  end
122
122
 
123
123
  result
@@ -147,7 +147,7 @@ module ElasticGraph
147
147
  query.result
148
148
  rescue => ex
149
149
  @logger.error <<~EOS
150
- Query #{query.operation_name}[1] for client #{client.description} failed with an exception[2].
150
+ Query #{query.selected_operation_name}[1] for client #{client.description} failed with an exception[2].
151
151
 
152
152
  [1] #{full_description_of(query)}
153
153
 
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -6,14 +6,13 @@
6
6
  #
7
7
  # frozen_string_literal: true
8
8
 
9
+ require "elastic_graph/constants"
9
10
  require "time"
10
11
 
11
12
  module ElasticGraph
12
13
  class GraphQL
13
14
  module ScalarCoercionAdapters
14
15
  class DateTime
15
- PRECISION = 3 # millisecond precision
16
-
17
16
  def self.coerce_input(value, ctx)
18
17
  return value if value.nil?
19
18
 
@@ -33,7 +32,7 @@ module ElasticGraph
33
32
  # format, so here we convert it to that format (which is just ISO8601 format). Ultimately,
34
33
  # that means that this method just "roundtrips" the input string back to a string, but it validates
35
34
  # the string is formatted correctly and returns a string in the exact format we need for the datastore.
36
- time.iso8601(PRECISION)
35
+ time.iso8601(DATE_TIME_PRECISION)
37
36
  rescue ::ArgumentError, ::TypeError
38
37
  raise_coercion_error(value)
39
38
  end
@@ -41,9 +40,9 @@ module ElasticGraph
41
40
  def self.coerce_result(value, ctx)
42
41
  case value
43
42
  when ::Time
44
- value.iso8601(PRECISION)
43
+ value.iso8601(DATE_TIME_PRECISION)
45
44
  when ::String
46
- ::Time.iso8601(value).iso8601(PRECISION)
45
+ ::Time.iso8601(value).iso8601(DATE_TIME_PRECISION)
47
46
  end
48
47
  rescue ::ArgumentError
49
48
  nil
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -19,12 +19,19 @@ module ElasticGraph
19
19
  class Type
20
20
  attr_reader :graphql_type, :fields_by_name, :index_definitions, :elasticgraph_category, :graphql_only_return_type
21
21
 
22
+ # Returns the grouping missing value placeholder for this type, if one is defined.
23
+ # This is used to handle missing values in aggregations without creating separate
24
+ # missing subaggregations, reducing the exponential explosion of subaggregations.
25
+ # @return [String, Numeric, nil] the placeholder value to use for missing values in grouping operations
26
+ attr_reader :grouping_missing_value_placeholder
27
+
22
28
  def initialize(
23
29
  schema,
24
30
  graphql_type,
25
31
  index_definitions,
26
32
  object_runtime_metadata,
27
33
  enum_runtime_metadata,
34
+ scalar_runtime_metadata,
28
35
  resolvers_needing_lookahead
29
36
  )
30
37
  @schema = schema
@@ -44,6 +51,7 @@ module ElasticGraph
44
51
  end
45
52
 
46
53
  @fields_by_name = build_fields_by_name_hash(schema, graphql_type).freeze
54
+ @grouping_missing_value_placeholder = determine_grouping_missing_value_placeholder(scalar_runtime_metadata&.grouping_missing_value_placeholder)
47
55
  end
48
56
 
49
57
  def name
@@ -232,6 +240,21 @@ module ElasticGraph
232
240
 
233
241
  private
234
242
 
243
+ def determine_grouping_missing_value_placeholder(scalar_placeholder)
244
+ if enum?
245
+ MISSING_ENUM_PLACEHOLDER
246
+ elsif scalar_placeholder == MISSING_STRING_PLACEHOLDER
247
+ # We replace the MISSING_STRING_PLACEHOLDER ($SECURE_RANDOM) with the secure random value
248
+ # generated and stored at MISSING_STRING_PLACEHOLDER_VALUE.
249
+ MISSING_STRING_PLACEHOLDER_VALUE
250
+ else
251
+ # Note that if the type is not a scalar then scalar_placeholder will be nil.
252
+ # We don't use missing value placeholders (or group aggregations) on fields
253
+ # that are not scalars or enums.
254
+ scalar_placeholder
255
+ end
256
+ end
257
+
235
258
  def lookup_enum_value_by_name(enum_value_name)
236
259
  graphql_enum_value = @graphql_type.values.fetch(enum_value_name)
237
260
 
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -53,6 +53,7 @@ module ElasticGraph
53
53
  index_definitions_by_graphql_type[key.graphql_name] || [],
54
54
  runtime_metadata.object_types_by_name[key.graphql_name],
55
55
  runtime_metadata.enum_types_by_name[key.graphql_name],
56
+ runtime_metadata.scalar_types_by_name[key.graphql_name],
56
57
  resolvers_needing_lookahead
57
58
  )
58
59
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2024 - 2025 Block, Inc.
1
+ # Copyright 2024 - 2026 Block, Inc.
2
2
  #
3
3
  # Use of this source code is governed by an MIT-style
4
4
  # license that can be found in the LICENSE file or at
@@ -8,7 +8,7 @@ updated_code_filename = "#{__dir__}/../../tmp/updated_valid_time_zones.rb"
8
8
  java_time_zones = `java --source 11 #{__dir__}/dump_time_zones.java`.split("\n")
9
9
 
10
10
  ::File.write(updated_code_filename, <<~EOS)
11
- # Copyright 2024 - 2025 Block, Inc.
11
+ # Copyright 2024 - 2026 Block, Inc.
12
12
  #
13
13
  # Use of this source code is governed by an MIT-style
14
14
  # license that can be found in the LICENSE file or at
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elasticgraph-graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Myron Marston
@@ -31,42 +31,42 @@ dependencies:
31
31
  requirements:
32
32
  - - '='
33
33
  - !ruby/object:Gem::Version
34
- version: 1.0.2
34
+ version: 1.0.3.rc1
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - '='
40
40
  - !ruby/object:Gem::Version
41
- version: 1.0.2
41
+ version: 1.0.3.rc1
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: elasticgraph-schema_artifacts
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - '='
47
47
  - !ruby/object:Gem::Version
48
- version: 1.0.2
48
+ version: 1.0.3.rc1
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
53
  - - '='
54
54
  - !ruby/object:Gem::Version
55
- version: 1.0.2
55
+ version: 1.0.3.rc1
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: graphql
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - '='
60
+ - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: 2.5.11
62
+ version: 2.5.18
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - '='
67
+ - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: 2.5.11
69
+ version: 2.5.18
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: graphql-c_parser
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -93,70 +93,70 @@ dependencies:
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 1.0.2
96
+ version: 1.0.3.rc1
97
97
  type: :development
98
98
  prerelease: false
99
99
  version_requirements: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - '='
102
102
  - !ruby/object:Gem::Version
103
- version: 1.0.2
103
+ version: 1.0.3.rc1
104
104
  - !ruby/object:Gem::Dependency
105
105
  name: elasticgraph-elasticsearch
106
106
  requirement: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - '='
109
109
  - !ruby/object:Gem::Version
110
- version: 1.0.2
110
+ version: 1.0.3.rc1
111
111
  type: :development
112
112
  prerelease: false
113
113
  version_requirements: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: 1.0.2
117
+ version: 1.0.3.rc1
118
118
  - !ruby/object:Gem::Dependency
119
119
  name: elasticgraph-opensearch
120
120
  requirement: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
- version: 1.0.2
124
+ version: 1.0.3.rc1
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - '='
130
130
  - !ruby/object:Gem::Version
131
- version: 1.0.2
131
+ version: 1.0.3.rc1
132
132
  - !ruby/object:Gem::Dependency
133
133
  name: elasticgraph-indexer
134
134
  requirement: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - '='
137
137
  - !ruby/object:Gem::Version
138
- version: 1.0.2
138
+ version: 1.0.3.rc1
139
139
  type: :development
140
140
  prerelease: false
141
141
  version_requirements: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - '='
144
144
  - !ruby/object:Gem::Version
145
- version: 1.0.2
145
+ version: 1.0.3.rc1
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: elasticgraph-schema_definition
148
148
  requirement: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
- version: 1.0.2
152
+ version: 1.0.3.rc1
153
153
  type: :development
154
154
  prerelease: false
155
155
  version_requirements: !ruby/object:Gem::Requirement
156
156
  requirements:
157
157
  - - '='
158
158
  - !ruby/object:Gem::Version
159
- version: 1.0.2
159
+ version: 1.0.3.rc1
160
160
  email:
161
161
  - myron@squareup.com
162
162
  executables: []
@@ -247,10 +247,10 @@ licenses:
247
247
  - MIT
248
248
  metadata:
249
249
  bug_tracker_uri: https://github.com/block/elasticgraph/issues
250
- changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.0.2
251
- documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.0.2/
250
+ changelog_uri: https://github.com/block/elasticgraph/releases/tag/v1.0.3.rc1
251
+ documentation_uri: https://block.github.io/elasticgraph/api-docs/v1.0.3.rc1/
252
252
  homepage_uri: https://block.github.io/elasticgraph/
253
- source_code_uri: https://github.com/block/elasticgraph/tree/v1.0.2/elasticgraph-graphql
253
+ source_code_uri: https://github.com/block/elasticgraph/tree/v1.0.3.rc1/elasticgraph-graphql
254
254
  gem_category: core
255
255
  rdoc_options: []
256
256
  require_paths:
@@ -262,14 +262,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
262
262
  version: '3.4'
263
263
  - - "<"
264
264
  - !ruby/object:Gem::Version
265
- version: '3.5'
265
+ version: '4.1'
266
266
  required_rubygems_version: !ruby/object:Gem::Requirement
267
267
  requirements:
268
268
  - - ">="
269
269
  - !ruby/object:Gem::Version
270
270
  version: '0'
271
271
  requirements: []
272
- rubygems_version: 3.6.9
272
+ rubygems_version: 4.0.3
273
273
  specification_version: 4
274
274
  summary: Provides the ElasticGraph GraphQL query engine.
275
275
  test_files: []