willholley commented on code in PR #4662:
URL: https://github.com/apache/couchdb/pull/4662#discussion_r1262323155
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
+
+In the next round, :ref:`partial indexes <find/partial_indexes>` are
+eliminated unless they are not requested explicitly, they are not
+considered automatically. When not specified, partial indexes are
+pushed back to the list of candidate indexes with the ``is_partial``
+code.
+
+After that, indexes that are different from the partition for which
+the query was issued are removed. That is, if the query applies to
+specific partition, global indexes and indexes for every other
+partition are discarded because they would not be able to support the
+execution, and vice versa. Such indexes are associated with the
+``scope_mismatch`` reason code.
+
+The remaining indexes are filtered by a series of usability checks.
+These checks depend on the type of index.
+
+- ``"special"``: The selector must reference the ``_id`` field,
+ sorting could be requested on ``_id`` only.
Review Comment:
"The selector must reference the ``_id`` field". This is the fallback index
so doesn't require the selector to explicitly reference the `_id` field.
```suggestion
- ``"special"``: Usable if no ``sort`` is specified in the query or ``sort``
is specified on ``_id`` only.
```
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
Review Comment:
What does `Whenever possible` mean here? I expected `_all_docs` to always be
included.
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
+
+In the next round, :ref:`partial indexes <find/partial_indexes>` are
+eliminated unless they are not requested explicitly, they are not
+considered automatically. When not specified, partial indexes are
+pushed back to the list of candidate indexes with the ``is_partial``
+code.
Review Comment:
```suggestion
In the next round, :ref:`partial indexes <find/partial_indexes>` are
eliminated unless specified in the `use_index` field of the query object.
```
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
+
+In the next round, :ref:`partial indexes <find/partial_indexes>` are
+eliminated unless they are not requested explicitly, they are not
+considered automatically. When not specified, partial indexes are
+pushed back to the list of candidate indexes with the ``is_partial``
+code.
+
+After that, indexes that are different from the partition for which
+the query was issued are removed. That is, if the query applies to
+specific partition, global indexes and indexes for every other
+partition are discarded because they would not be able to support the
+execution, and vice versa. Such indexes are associated with the
+``scope_mismatch`` reason code.
+
+The remaining indexes are filtered by a series of usability checks.
+These checks depend on the type of index.
+
+- ``"special"``: The selector must reference the ``_id`` field,
+ sorting could be requested on ``_id`` only.
+
+- ``"json"``: The selector must not request a free-form text search
+ via the ``$text`` operator, and all the columns that are restricted
+ by the selector must exist in the index. Sort fields are required
+ to exist as well.
+
+- ``"text"``: The selector must contain references to fields that are
+ indexable. Sometimes it cannot be pre-determined if the given field
+ would exist in the text index, hence it will not be supported.
+
+Each usability check is supplied with its own reason code. That is
+``field_mismatch`` for the cases when the fields in the index do not
+match with that of the selector. The code ``sort_order_mismatch``
+means that the requested sorting does not align with the index. The
+code ``needs_text_search`` refers to the case when an index of type
+``"text"`` would be required. The ``"text"`` indexes do not work
+empty selectors, and they return a ``empty_selector`` reason code in
+response to that.
Review Comment:
I think we should have a distinct list/table of the reason codes that could
be returned. For these that are specific to the usability checks, additionally
add them to the check descriptions above.
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
Review Comment:
A diagram here outlining the flow might be useful.
https://docs.couchdb.org/en/stable/replication/replicator.html#replication-states
has some prior art.
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
+
+In the next round, :ref:`partial indexes <find/partial_indexes>` are
+eliminated unless they are not requested explicitly, they are not
+considered automatically. When not specified, partial indexes are
+pushed back to the list of candidate indexes with the ``is_partial``
+code.
+
+After that, indexes that are different from the partition for which
+the query was issued are removed. That is, if the query applies to
+specific partition, global indexes and indexes for every other
+partition are discarded because they would not be able to support the
+execution, and vice versa. Such indexes are associated with the
+``scope_mismatch`` reason code.
+
+The remaining indexes are filtered by a series of usability checks.
+These checks depend on the type of index.
+
+- ``"special"``: The selector must reference the ``_id`` field,
+ sorting could be requested on ``_id`` only.
+
+- ``"json"``: The selector must not request a free-form text search
+ via the ``$text`` operator, and all the columns that are restricted
+ by the selector must exist in the index. Sort fields are required
+ to exist as well.
Review Comment:
"columns" is internal terminology - I don't think it makes sense in
user-facing documentation.
```suggestion
- ``"json"``: The selector must not request a free-form text search
via the ``$text`` operator.
All the fields in the index must be referenced by the ``selector`` or
``sort`` in the query.
Any ``sort`` specified in the query must match the order of fields the
index.
```
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
+
+In the next round, :ref:`partial indexes <find/partial_indexes>` are
+eliminated unless they are not requested explicitly, they are not
+considered automatically. When not specified, partial indexes are
+pushed back to the list of candidate indexes with the ``is_partial``
+code.
+
+After that, indexes that are different from the partition for which
+the query was issued are removed. That is, if the query applies to
+specific partition, global indexes and indexes for every other
+partition are discarded because they would not be able to support the
+execution, and vice versa. Such indexes are associated with the
+``scope_mismatch`` reason code.
Review Comment:
```suggestion
After that, indexes are filtered according whether a global or partitioned
query was issued. Indexes that do not match the query scope are assigned a
``scope_mismatch`` reason code.
```
##########
src/docs/src/api/database/find.rst:
##########
@@ -1508,22 +1514,151 @@ it easier to take advantage of future improvements to
query planning
"title"
],
"partitioned": false
+ "index_candidates": [
+ {
+ "index": {
+ "ddoc": null,
+ "name": "_all_docs",
+ "type": "special",
+ "def": {
+ "fields": [
+ {
+ "_id": "asc"
+ }
+ ]
+ }
+ },
+ "usable": true,
+ "reason": "unfavored_type",
+ "ranking": 1
+ }
+ ],
+ "selector_hints": {
+ "indexable_fields": {
+ "json": [
+ "year"
+ ]
+ },
+ "unindexable_fields": {
+ "json": []
+ }
+ }
}
+.. _find/index_selection:
+
Index selection
===============
:ref:`_find <api/db/_find>` chooses which index to use for responding
-to a query, unless you specify an index at query time.
+to a query, unless you specify an index at query time. In this
+section, a brief overview of the index selection process is presented.
-The query planner looks at the selector section and finds the index with the
-closest match to operators and fields used in the query. If there are two
-or more json type indexes that match, the index with the smallest
-number of fields in the index is preferred.
-If there are still two or more candidate indexes,
-the index with the first alphabetical name is chosen.
+.. note::
+
+ It is good practice to specify indexes explicitly in your
+ queries. This prevents existing queries being affected by new
+ indexes that might get added in a production environment.
.. note::
- It is good practice to specify indexes explicitly in your queries. This
- prevents existing queries being affected by new indexes that might get
added
- in a production environment.
+
+ Both the :ref:`_explain <api/db/find/explain>` and :ref:`_find
+ <api/db/_find>` endpoints rely on the same index selection logic.
+ But :ref:`_explain <api/db/find/explain>` is a bit more elaborate,
+ therefore it could be used for simulation and exploration. In the
+ output, reasons for discarding indexes are placed in the ``reason``
+ field of the JSON objects under ``index_candidates``. Each reason
+ has a specific code, which will be mentioned at the relevant
+ subsections below.
+
+The index selection happens in multiple rounds.
+
+First, all the indexes for the database are collected. Whenever
+possible, the result includes the special index called `all docs`
+which is a trivial index on the ``_id`` field. This is reserved as a
+catch-all answer when no other suitable indexes could be found, but
+its use of discouraged for performance reasons.
+
+In the next round, :ref:`partial indexes <find/partial_indexes>` are
+eliminated unless they are not requested explicitly, they are not
+considered automatically. When not specified, partial indexes are
+pushed back to the list of candidate indexes with the ``is_partial``
+code.
+
+After that, indexes that are different from the partition for which
+the query was issued are removed. That is, if the query applies to
+specific partition, global indexes and indexes for every other
+partition are discarded because they would not be able to support the
+execution, and vice versa. Such indexes are associated with the
+``scope_mismatch`` reason code.
+
+The remaining indexes are filtered by a series of usability checks.
+These checks depend on the type of index.
+
+- ``"special"``: The selector must reference the ``_id`` field,
+ sorting could be requested on ``_id`` only.
+
+- ``"json"``: The selector must not request a free-form text search
+ via the ``$text`` operator, and all the columns that are restricted
+ by the selector must exist in the index. Sort fields are required
+ to exist as well.
+
+- ``"text"``: The selector must contain references to fields that are
+ indexable. Sometimes it cannot be pre-determined if the given field
+ would exist in the text index, hence it will not be supported.
Review Comment:
I'm not entirely clear what "fields that are indexable" means here.
Can you provide an example of a situation where we cannot determine whether
a field will exist in a text index?
```suggestion
- ``"text"``: The index must contain fields that are referenced by the query
``"selector"`` or ``"sort"``. Sometimes it cannot be predetermined that a field
will exist in a text index, in which case the text index will not be supported.
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]