Skip to content

Commit 0d810a0

Browse files
authored
Rename __count meta field to _x_count and release v1.10.0. (kensho-technologies#176)
* Rename __count meta field to _x_count and release v1.10.0. * Fix changelog link to PR. * Update with link to GraphQL spec.
1 parent a114ae3 commit 0d810a0

File tree

11 files changed

+51
-40
lines changed

11 files changed

+51
-40
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Current development version
44

5+
## v1.10.0
6+
7+
- **BREAKING**: Rename the `__count` meta field to `_x_count`, to avoid GraphQL schema parsing issues with other GraphQL libraries. [#176](https://github.com/kensho-technologies/graphql-compiler/pull/176)
8+
59
## v1.9.0
610

711
- Add a `__count` meta field that supports outputting and filtering on the size of a `@fold` scope. [#158](https://github.com/kensho-technologies/graphql-compiler/pull/158)

README.md

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ It's modeled after Python's `json.tool`, reading from stdin and writing to stdou
4646
* [Type coercions](#type-coercions)
4747
* [Meta fields](#meta-fields)
4848
* [\__typename](#__typename)
49-
* [\__count](#__count)
49+
* [\_x_count](#_x_count)
5050
* [The GraphQL schema](#the-graphql-schema)
5151
* [Execution model](#execution-model)
5252
* [Miscellaneous](#miscellaneous)
@@ -790,16 +790,23 @@ and others. Vertices of all subtypes of `Entity` will therefore be returned, and
790790
column that outputs the `__typename` field will show their runtime type: `Animal`, `Species`,
791791
`Food`, etc.
792792

793-
### \_\_count
793+
### \_x\_count
794794

795-
The `__count` meta field is a non-standard meta field defined by the GraphQL compiler that makes it
795+
The `_x_count` meta field is a non-standard meta field defined by the GraphQL compiler that makes it
796796
possible to interact with the _number_ of elements in a scope marked `@fold`. By applying directives
797797
like `@output` and `@filter` to this meta field, queries can output the number of elements captured
798798
in the `@fold` and filter down results to select only those with the desired fold sizes.
799799

800-
#### Adding the `__count` meta field to your schema
800+
We use the `_x_` prefix to signify that this is an extension meta field introduced by the compiler,
801+
and not part of the canonical set of GraphQL meta fields defined by the GraphQL specification.
802+
We do not use the GraphQL standard double-underscore (`__`) prefix for meta fields,
803+
since all names with that prefix are
804+
[explicitly reserved and prohibited from being used](https://facebook.github.io/graphql/draft/#sec-Reserved-Names)
805+
in directives, fields, or any other artifacts.
801806

802-
Since the `__count` meta field is not currently part of the GraphQL standard, it has to be
807+
#### Adding the `_x_count` meta field to your schema
808+
809+
Since the `_x_count` meta field is not currently part of the GraphQL standard, it has to be
803810
explicitly added to all interfaces and types in your schema. There are two ways to do this.
804811

805812
The preferred way to do this is to use the `EXTENDED_META_FIELD_DEFINITIONS` constant as
@@ -834,7 +841,7 @@ insert_meta_fields_into_existing_schema(existing_schema)
834841
Animal {
835842
name @output(out_name: "name")
836843
out_Animal_ParentOf @fold {
837-
__count @output(out_name: "number_of_children")
844+
_x_count @output(out_name: "number_of_children")
838845
name @output(out_name: "child_names")
839846
}
840847
}
@@ -849,7 +856,7 @@ the output type of the `number_of_children` selection is an integer.
849856
Animal {
850857
name @output(out_name: "name")
851858
out_Animal_ParentOf @fold {
852-
__count @filter(op_name: ">=", value: ["$min_children"])
859+
_x_count @filter(op_name: ">=", value: ["$min_children"])
853860
@output(out_name: "number_of_children")
854861
name @filter(op_name: "has_substring", value: ["$substr"])
855862
@output(out_name: "child_names")
@@ -861,24 +868,24 @@ Here, we've modified the above query to add two more filtering constraints to th
861868
- child `Animal` vertices must contain the value of `$substr` as a substring in their name, and
862869
- `Animal` vertices must have at least `$min_children` children that satisfy the above filter.
863870

864-
Importantly, any filtering on `__count` is applied *after* any other filters and type coercions
871+
Importantly, any filtering on `_x_count` is applied *after* any other filters and type coercions
865872
that are present in the `@fold` in question. This order of operations matters a lot: selecting
866873
`Animal` vertices with 3+ children, then filtering the children based on their names is not the same
867874
as filtering the children first, and then selecting `Animal` vertices that have 3+ children that
868875
matched the earlier filter.
869876

870877
#### Constraints and Rules
871-
- The `__count` field is only allowed to appear within a vertex field marked `@fold`.
872-
- Filtering on `__count` is always applied *after* any other filters and type coercions present
878+
- The `_x_count` field is only allowed to appear within a vertex field marked `@fold`.
879+
- Filtering on `_x_count` is always applied *after* any other filters and type coercions present
873880
in that `@fold`.
874-
- Filtering or outputting the value of the `__count` field must always be done at the innermost
881+
- Filtering or outputting the value of the `_x_count` field must always be done at the innermost
875882
scope of the `@fold`. It is invalid to expand vertex fields within a `@fold` after filtering
876-
or outputting the value of the `__count` meta field.
883+
or outputting the value of the `_x_count` meta field.
877884

878-
#### How is filtering on `__count` different from `@filter` with `has_edge_degree`?
885+
#### How is filtering on `_x_count` different from `@filter` with `has_edge_degree`?
879886

880887
The `has_edge_degree` filter allows filtering based on the number of edges of a particular type.
881-
There are situations in which filtering with `has_edge_degree` and filtering using `=` on `__count`
888+
There are situations in which filtering with `has_edge_degree` and filtering using `=` on `_x_count`
882889
produce equivalent queries. Here is one such pair of queries:
883890
```
884891
{
@@ -896,7 +903,7 @@ and
896903
Species {
897904
name @output(out_name: "name")
898905
in_Animal_OfSpecies @fold {
899-
__count @filter(op_name: "=", value: ["$num_animals"])
906+
_x_count @filter(op_name: "=", value: ["$num_animals"])
900907
}
901908
}
902909
}
@@ -928,7 +935,7 @@ versus
928935
name @output(out_name: "name")
929936
in_Animal_OfSpecies @fold {
930937
out_Animal_LivesIn {
931-
__count @filter(op_name: "=", value: ["$num_animals"])
938+
_x_count @filter(op_name: "=", value: ["$num_animals"])
932939
name @filter(op_name: "=", value: ["$location"])
933940
}
934941
}
@@ -939,7 +946,7 @@ In the first, for the purposes of the `has_edge_degree` filtering, the location
939946
live is irrelevant: the `has_edge_degree` only makes sure that the `Species` vertex has the
940947
correct number of edges of type `in_Animal_OfSpecies`, and that's it. In contrast, the second query
941948
ensures that only `Species` vertices that have `$num_animals` animals that live in the selected
942-
location are returned -- the location matters since the `@filter` on the `__count` field applies
949+
location are returned -- the location matters since the `@filter` on the `_x_count` field applies
943950
to the number of elements in the `@fold` scope.
944951

945952
## The GraphQL schema

graphql_compiler/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121

2222
__package_name__ = 'graphql-compiler'
23-
__version__ = '1.9.0'
23+
__version__ = '1.10.0'
2424

2525

2626
def graphql_to_match(schema, graphql_query, parameters, type_equivalence_hints=None):

graphql_compiler/compiler/blocks.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ class GlobalOperationsStart(MarkerBlock):
478478
479479
Global operations include, for example, various kinds of filters that affect more than one
480480
location in the query. Such filters are produced, e.g., as part of nested-optional processing,
481-
or when filters are applied to the "__count" meta property.
481+
or when filters are applied to the "_x_count" meta property.
482482
"""
483483

484484
__slots__ = ()

graphql_compiler/compiler/compiler_frontend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ def _validate_fold_has_outputs_or_count_filter(fold_scope_location, fold_has_cou
564564
# This function makes sure that the @fold scope has an effect.
565565
# Folds either output data, or filter the data enclosing the fold based on the size of the fold.
566566
if fold_has_count_filter:
567-
# This fold has a filter on the "__count" property, so it is legal and has an effect.
567+
# This fold has a filter on the "_x_count" property, so it is legal and has an effect.
568568
return True
569569

570570
# At least one output in the outputs list must point to the fold_scope_location,

graphql_compiler/compiler/context_helpers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def set_fold_scope_data(context, data):
4848

4949

5050
def has_fold_count_filter(context):
51-
"""Return True if the current context contains a filter on the __count field."""
51+
"""Return True if the current context contains a filter on the _x_count field."""
5252
return CONTEXT_FOLD_HAS_COUNT_FILTER in context
5353

5454

@@ -58,7 +58,7 @@ def unmark_fold_count_filter(context):
5858

5959

6060
def set_fold_count_filter(context):
61-
"""Set a mark indicating the presence of a filter on a fold __count field."""
61+
"""Set a mark indicating the presence of a filter on a fold _x_count field."""
6262
context[CONTEXT_FOLD_HAS_COUNT_FILTER] = True
6363

6464

graphql_compiler/compiler/expressions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ def validate(self):
505505

506506
if self.fold_scope_location.field == COUNT_META_FIELD_NAME:
507507
if not GraphQLInt.is_same_type(self.field_type):
508-
raise TypeError(u'Expected the __count meta-field to be of GraphQLInt type, but '
508+
raise TypeError(u'Expected the _x_count meta-field to be of GraphQLInt type, but '
509509
u'encountered type {} instead: {}'
510510
.format(self.field_type, self.fold_scope_location))
511511
else:

graphql_compiler/schema.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def _parse_datetime_value(value):
280280

281281

282282
TYPENAME_META_FIELD_NAME = '__typename' # This meta field is built-in.
283-
COUNT_META_FIELD_NAME = '__count'
283+
COUNT_META_FIELD_NAME = '_x_count'
284284

285285

286286
ALL_SUPPORTED_META_FIELDS = frozenset((
@@ -311,7 +311,7 @@ def insert_meta_fields_into_existing_schema(graphql_schema):
311311
Use this function at your own risk. Don't say you haven't been warned.
312312
313313
Properties added include:
314-
- "__count", which allows filtering folds based on the number of elements they capture.
314+
- "_x_count", which allows filtering folds based on the number of elements they capture.
315315
316316
Args:
317317
graphql_schema: GraphQLSchema object describing the schema that is going to be used with

graphql_compiler/tests/test_input_data.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,7 +1890,7 @@ def output_count_in_fold_scope():
18901890
Animal {
18911891
name @output(out_name: "name")
18921892
out_Animal_ParentOf @fold {
1893-
__count @output(out_name: "number_of_children")
1893+
_x_count @output(out_name: "number_of_children")
18941894
name @output(out_name: "child_names")
18951895
}
18961896
}
@@ -1914,7 +1914,7 @@ def filter_count_with_runtime_parameter_in_fold_scope():
19141914
Animal {
19151915
name @output(out_name: "name")
19161916
out_Animal_ParentOf @fold {
1917-
__count @filter(op_name: ">=", value: ["$min_children"])
1917+
_x_count @filter(op_name: ">=", value: ["$min_children"])
19181918
name @output(out_name: "child_names")
19191919
}
19201920
}
@@ -1942,7 +1942,7 @@ def filter_count_with_tagged_parameter_in_fold_scope():
19421942
limbs @tag(tag_name: "limbs")
19431943
}
19441944
out_Animal_ParentOf @fold {
1945-
__count @filter(op_name: ">=", value: ["%limbs"])
1945+
_x_count @filter(op_name: ">=", value: ["%limbs"])
19461946
name @output(out_name: "child_names")
19471947
}
19481948
}
@@ -1965,7 +1965,7 @@ def filter_count_and_other_filters_in_fold_scope():
19651965
Animal {
19661966
name @output(out_name: "name")
19671967
out_Animal_ParentOf @fold {
1968-
__count @filter(op_name: ">=", value: ["$min_children"])
1968+
_x_count @filter(op_name: ">=", value: ["$min_children"])
19691969
@output(out_name: "number_of_children")
19701970
alias @filter(op_name: "contains", value: ["$expected_alias"])
19711971
}
@@ -1992,10 +1992,10 @@ def multiple_filters_on_count():
19921992
Animal {
19931993
name @output(out_name: "name")
19941994
out_Animal_ParentOf @fold {
1995-
__count @filter(op_name: ">=", value: ["$min_children"])
1995+
_x_count @filter(op_name: ">=", value: ["$min_children"])
19961996
}
19971997
out_Entity_Related @fold {
1998-
__count @filter(op_name: ">=", value: ["$min_related"])
1998+
_x_count @filter(op_name: ">=", value: ["$min_related"])
19991999
}
20002000
}
20012001
}'''
@@ -2020,7 +2020,7 @@ def filter_on_count_with_nested_filter():
20202020
name @output(out_name: "name")
20212021
in_Animal_OfSpecies @fold {
20222022
out_Animal_LivesIn {
2023-
__count @filter(op_name: "=", value: ["$num_animals"])
2023+
_x_count @filter(op_name: "=", value: ["$num_animals"])
20242024
name @filter(op_name: "=", value: ["$location"])
20252025
}
20262026
}

graphql_compiler/tests/test_ir_generation_errors.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ def test_fold_directive_constraints(self):
317317
Animal {
318318
name @output(out_name: "name")
319319
out_Animal_ParentOf {
320-
__count @output(out_name: "child_count")
320+
_x_count @output(out_name: "child_count")
321321
}
322322
}
323323
}'''
@@ -326,7 +326,7 @@ def test_fold_directive_constraints(self):
326326
Species {
327327
name @output(out_name: "name")
328328
in_Animal_OfSpecies @fold {
329-
__count @output(out_name: "fold_size")
329+
_x_count @output(out_name: "fold_size")
330330
out_Animal_LivesIn {
331331
name @filter(op_name: "=", value: ["$location"])
332332
}
@@ -338,9 +338,9 @@ def test_fold_directive_constraints(self):
338338
Species {
339339
name @output(out_name: "name")
340340
in_Animal_OfSpecies @fold {
341-
__count @output(out_name: "fold_size")
341+
_x_count @output(out_name: "fold_size")
342342
out_Animal_LivesIn {
343-
__count @filter(op_name: "=", value: ["$num_animals"])
343+
_x_count @filter(op_name: "=", value: ["$num_animals"])
344344
}
345345
}
346346
}
@@ -350,9 +350,9 @@ def test_fold_directive_constraints(self):
350350
Species {
351351
name @output(out_name: "name")
352352
in_Animal_OfSpecies @fold {
353-
__count @filter(op_name: "=", value: ["$num_animals"])
353+
_x_count @filter(op_name: "=", value: ["$num_animals"])
354354
out_Animal_LivesIn {
355-
__count @output(out_name: "fold_size")
355+
_x_count @output(out_name: "fold_size")
356356
}
357357
}
358358
}
@@ -485,7 +485,7 @@ def test_tag_directive_constraints(self):
485485
Animal {
486486
name @output(out_name: "name")
487487
out_Animal_ParentOf {
488-
__count @tag(tag_name: "count")
488+
_x_count @tag(tag_name: "count")
489489
}
490490
}
491491
}''')

0 commit comments

Comments
 (0)