Skip to content

Commit 49bca20

Browse files
authored
Make driver reject unknown query type in summary (#602)
* Make driver reject unknown query type in summary * Add unresolved_address attribute to ConnectionStub This fixes unit tests. A real connection has this attribute. The lack of it in the stub was unnoticed as it was not needed in any tests.
1 parent edb07f7 commit 49bca20

File tree

4 files changed

+26
-5
lines changed

4 files changed

+26
-5
lines changed

neo4j/work/result.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,14 @@ def _obtain_summary(self):
234234
"""
235235
if self._summary is None:
236236
if self._metadata:
237-
self._summary = ResultSummary(**self._metadata)
237+
self._summary = ResultSummary(
238+
self._connection.unresolved_address, **self._metadata
239+
)
238240
elif self._connection:
239-
self._summary = ResultSummary(server=self._connection.server_info)
241+
self._summary = ResultSummary(
242+
self._connection.unresolved_address,
243+
server=self._connection.server_info
244+
)
240245

241246
return self._summary
242247

neo4j/work/summary.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
from collections import namedtuple
2323

24+
from neo4j._exceptions import BoltProtocolError
25+
2426
BOLT_VERSION_1 = 1
2527
BOLT_VERSION_2 = 2
2628
BOLT_VERSION_3 = 3
@@ -45,7 +47,9 @@ class ResultSummary:
4547
#: Dictionary of parameters passed with the statement.
4648
parameters = None
4749

48-
#: A string that describes the type of query (``'r'`` = read-only, ``'rw'`` = read/write).
50+
#: A string that describes the type of query
51+
# ``'r'`` = read-only, ``'rw'`` = read/write, ``'w'`` = write-onlye,
52+
# ``'s'`` = schema.
4953
query_type = None
5054

5155
#: A :class:`neo4j.SummaryCounters` instance. Counters for operations the query triggered.
@@ -70,12 +74,19 @@ class ResultSummary:
7074
#: Unlike failures or errors, notifications do not affect the execution of a statement.
7175
notifications = None
7276

73-
def __init__(self, **metadata):
77+
def __init__(self, address, **metadata):
7478
self.metadata = metadata
7579
self.server = metadata.get("server")
7680
self.database = metadata.get("db")
7781
self.query = metadata.get("query")
7882
self.parameters = metadata.get("parameters")
83+
if "type" in metadata:
84+
self.query_type = metadata["type"]
85+
if self.query_type not in ["r", "w", "rw", "s"]:
86+
raise BoltProtocolError(
87+
"Unexpected query type '%s' received from server. Consider "
88+
"updating the driver.", address
89+
)
7990
self.query_type = metadata.get("type")
8091
self.plan = metadata.get("plan")
8192
self.profile = metadata.get("profile")

testkitbackend/backend.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
import sys
2525
import traceback
2626

27+
from neo4j._exceptions import (
28+
BoltError
29+
)
2730
from neo4j.exceptions import (
2831
DriverError,
2932
Neo4jError,
@@ -152,7 +155,8 @@ def _process(self, request):
152155
"Backend does not support some properties of the " + name +
153156
" request: " + ", ".join(unsused_keys)
154157
)
155-
except (Neo4jError, DriverError, UnsupportedServerProduct) as e:
158+
except (Neo4jError, DriverError, UnsupportedServerProduct,
159+
BoltError) as e:
156160
log.debug(traceback.format_exc())
157161
if isinstance(e, Neo4jError):
158162
msg = "" if e.message is None else str(e.message)

tests/unit/work/test_result.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def __init__(self, records=None, run_meta=None, summary_meta=None,
9898
self.run_meta = run_meta
9999
self.summary_meta = summary_meta
100100
ConnectionStub.server_info.update({"server": "Neo4j/4.3.0"})
101+
self.unresolved_address = None
101102

102103
def send_all(self):
103104
self.sent += self.queued

0 commit comments

Comments
 (0)