diff --git a/elasticgraph-schema_artifacts/lib/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rb b/elasticgraph-schema_artifacts/lib/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rb index ad3a843eb..0a39e2bd7 100644 --- a/elasticgraph-schema_artifacts/lib/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rb +++ b/elasticgraph-schema_artifacts/lib/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rb @@ -14,7 +14,7 @@ module RuntimeMetadata # Provides runtime metadata related to scalar types. # # @private - class ScalarType < ::Data.define(:coercion_adapter_ref, :indexing_preparer_ref) + class ScalarType < ::Data.define(:coercion_adapter_ref, :indexing_preparer_ref, :grouping_missing_value_placeholder) def self.coercion_adapter_extension_loader @coercion_adapter_extension_loader ||= ExtensionLoader.new(ScalarCoercionAdapterInterface) end @@ -41,11 +41,8 @@ def self.load_many(scalar_type_hashes_by_name) scalar_type_hashes_by_name.transform_values do |hash| new( coercion_adapter_ref: hash.fetch("coercion_adapter"), - # `indexing_preparer` is new as of Q4 2022, and as such is not present in schema artifacts - # dumped before then. Therefore, we allow for the key to not be present in the runtime - # metadata--important so that we don't have a "chicken and egg" problem where the rake tasks - # that need to be loaded to dump new schema artifacts fail at load time due to the missing key. - indexing_preparer_ref: hash.fetch("indexing_preparer", DEFAULT_INDEXING_PREPARER_REF) + indexing_preparer_ref: hash.fetch("indexing_preparer", DEFAULT_INDEXING_PREPARER_REF), + grouping_missing_value_placeholder: hash["grouping_missing_value_placeholder"] ) end end @@ -71,6 +68,7 @@ def to_dumpable_hash { # Keys here are ordered alphabetically; please keep them that way. "coercion_adapter" => load_coercion_adapter.to_dumpable_hash, + "grouping_missing_value_placeholder" => grouping_missing_value_placeholder, "indexing_preparer" => load_indexing_preparer.to_dumpable_hash } end diff --git a/elasticgraph-schema_artifacts/sig/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rbs b/elasticgraph-schema_artifacts/sig/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rbs index 76d19aca4..b236f500a 100644 --- a/elasticgraph-schema_artifacts/sig/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rbs +++ b/elasticgraph-schema_artifacts/sig/elastic_graph/schema_artifacts/runtime_metadata/scalar_type.rbs @@ -4,15 +4,18 @@ module ElasticGraph class ScalarTypeSupertype attr_reader coercion_adapter_ref: ::Hash[::String, ::String] attr_reader indexing_preparer_ref: ::Hash[::String, ::String] + attr_reader grouping_missing_value_placeholder: ::String? def initialize: ( coercion_adapter_ref: ::Hash[::String, ::String], - indexing_preparer_ref: ::Hash[::String, ::String] + indexing_preparer_ref: ::Hash[::String, ::String], + grouping_missing_value_placeholder: ::String? ) -> void def with: ( ?coercion_adapter_ref: ::Hash[::String, ::String], - ?indexing_preparer_ref: ::Hash[::String, ::String] + ?indexing_preparer_ref: ::Hash[::String, ::String], + ?grouping_missing_value_placeholder: ::String? ) -> ScalarType end diff --git a/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/scalar_type_spec.rb b/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/scalar_type_spec.rb index 72aa86fd7..ab3751958 100644 --- a/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/scalar_type_spec.rb +++ b/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/scalar_type_spec.rb @@ -18,7 +18,7 @@ module RuntimeMetadata include RuntimeMetadataSupport it "allows `with:` to be used to update a single attribute" do - scalar_type = ScalarType.new( + scalar_type = scalar_type_with( coercion_adapter_ref: scalar_coercion_adapter1.to_dumpable_hash, indexing_preparer_ref: indexing_preparer1.to_dumpable_hash ) diff --git a/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/schema_spec.rb b/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/schema_spec.rb index 91aada9d7..b403a27ae 100644 --- a/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/schema_spec.rb +++ b/elasticgraph-schema_artifacts/spec/unit/elastic_graph/schema_artifacts/runtime_metadata/schema_spec.rb @@ -90,23 +90,24 @@ module RuntimeMetadata ) }, scalar_types_by_name: { - "ScalarType1" => ScalarType.new( - scalar_coercion_adapter1.to_dumpable_hash, - indexing_preparer1.to_dumpable_hash + "ScalarType1" => scalar_type_with( + coercion_adapter_ref: scalar_coercion_adapter1.to_dumpable_hash, + indexing_preparer_ref: indexing_preparer1.to_dumpable_hash ), - "ScalarType2" => ScalarType.new( - scalar_coercion_adapter2.to_dumpable_hash, - indexing_preparer2.to_dumpable_hash + "ScalarType2" => scalar_type_with( + coercion_adapter_ref: scalar_coercion_adapter2.to_dumpable_hash, + indexing_preparer_ref: indexing_preparer2.to_dumpable_hash, + grouping_missing_value_placeholder: "NaN" ) }, enum_types_by_name: { - "WidgetSort" => Enum::Type.new({ - "id_ASC" => Enum::Value.new(SortField.new("id", :asc), nil, nil, nil), - "id_DESC" => Enum::Value.new(SortField.new("id", :desc), nil, nil, nil) + "WidgetSort" => enum_type_with(values_by_name: { + "id_ASC" => enum_value_with(sort_field: SortField.new("id", :asc)), + "id_DESC" => enum_value_with(sort_field: SortField.new("id", :desc)) }), - "DistanceUnit" => Enum::Type.new({ - "MILE" => Enum::Value.new(nil, nil, :mi, nil), - "KILOMETER" => Enum::Value.new(nil, nil, :km, nil) + "DistanceUnit" => enum_type_with(values_by_name: { + "MILE" => enum_value_with(datastore_abbreviation: :mi), + "KILOMETER" => enum_value_with(datastore_abbreviation: :km) }) }, index_definitions_by_name: { @@ -218,6 +219,7 @@ module RuntimeMetadata "name" => "ElasticGraph::SchemaArtifacts::ScalarCoercionAdapter2", "require_path" => "support/example_extensions/scalar_coercion_adapters" }, + "grouping_missing_value_placeholder" => "NaN", "indexing_preparer" => { "name" => "ElasticGraph::SchemaArtifacts::IndexingPreparer2", "require_path" => "support/example_extensions/indexing_preparers" @@ -331,8 +333,8 @@ module RuntimeMetadata it "ignores enum types that have no meaningful runtime metadata" do schema = schema_with(enum_types_by_name: { "HasValues" => enum_type_with(values_by_name: { - "id_ASC" => Enum::Value.new(SortField.new("id", :asc), nil, nil, nil), - "id_DESC" => Enum::Value.new(SortField.new("id", :desc), nil, nil, nil) + "id_ASC" => enum_value_with(sort_field: SortField.new("id", :asc)), + "id_DESC" => enum_value_with(sort_field: SortField.new("id", :desc)) }), "NoValues" => enum_type_with(values_by_name: {}) }) diff --git a/elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb b/elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb index 1769059b6..69db7c60f 100644 --- a/elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb +++ b/elasticgraph-schema_definition/lib/elastic_graph/schema_definition/schema_elements/scalar_type.rb @@ -71,7 +71,8 @@ def initialize(schema_def_state, name) # Default the runtime metadata before yielding, so it can be overridden as needed. self.runtime_metadata = SchemaArtifacts::RuntimeMetadata::ScalarType.new( coercion_adapter_ref: SchemaArtifacts::RuntimeMetadata::ScalarType::DEFAULT_COERCION_ADAPTER_REF, - indexing_preparer_ref: SchemaArtifacts::RuntimeMetadata::ScalarType::DEFAULT_INDEXING_PREPARER_REF + indexing_preparer_ref: SchemaArtifacts::RuntimeMetadata::ScalarType::DEFAULT_INDEXING_PREPARER_REF, + grouping_missing_value_placeholder: nil ) yield self diff --git a/spec_support/lib/elastic_graph/spec_support/runtime_metadata_support.rb b/spec_support/lib/elastic_graph/spec_support/runtime_metadata_support.rb index f96daccaf..69968fd39 100644 --- a/spec_support/lib/elastic_graph/spec_support/runtime_metadata_support.rb +++ b/spec_support/lib/elastic_graph/spec_support/runtime_metadata_support.rb @@ -130,6 +130,20 @@ def enum_type_with(values_by_name: {}) Enum::Type.new(values_by_name: values_by_name) end + def enum_value_with( + sort_field: nil, + datastore_value: nil, + datastore_abbreviation: nil, + alternate_original_name: nil + ) + Enum::Value.new( + sort_field: sort_field, + datastore_value: datastore_value, + datastore_abbreviation: datastore_abbreviation, + alternate_original_name: alternate_original_name + ) + end + def sort_field_with(field_path: "path.to.some.field", direction: :asc) SortField.new( field_path: field_path, @@ -168,11 +182,13 @@ def graphql_resolver_with(needs_lookahead: false, resolver_ref: DEFAULT_RESOLVER def scalar_type_with( coercion_adapter_ref: ScalarType::DEFAULT_COERCION_ADAPTER_REF, - indexing_preparer_ref: ScalarType::DEFAULT_INDEXING_PREPARER_REF + indexing_preparer_ref: ScalarType::DEFAULT_INDEXING_PREPARER_REF, + grouping_missing_value_placeholder: nil ) ScalarType.new( coercion_adapter_ref: coercion_adapter_ref, - indexing_preparer_ref: indexing_preparer_ref + indexing_preparer_ref: indexing_preparer_ref, + grouping_missing_value_placeholder: grouping_missing_value_placeholder ) end