Skip to content

Commit 0042da9

Browse files
committed
RDBC-1028: quote SuggestToken alias containing spaces in generated RQL
SuggestToken.write_to() emitted the alias unquoted, so multi-word display names (e.g. 'Customized name with spaces') broke the RQL parser on the server. Fix: pass the alias through QueryFieldUtil.escape_if_necessary(), matching the C# client's use of QueryFieldUtil.EscapeIfNecessary(). Regression test: test_suggest_alias_escaping.py verifies that a suggest alias containing spaces is wrapped in single quotes in the generated RQL.
1 parent 4e34616 commit 0042da9

2 files changed

Lines changed: 67 additions & 2 deletions

File tree

ravendb/documents/session/tokens/query_tokens/definitions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
from ravendb.documents.session.tokens.query_tokens.query_token import QueryToken
2323
from ravendb.documents.session.utils.document_query import DocumentQueryHelper
2424
from ravendb.primitives.constants import VectorSearch
25-
from ravendb.tools.utils import Utils
25+
from ravendb.tools.utils import Utils, QueryFieldUtil
2626

2727

2828
class CompareExchangeValueIncludesToken(QueryToken):
@@ -992,7 +992,7 @@ def write_to(self, writer: List[str]) -> None:
992992
return
993993

994994
writer.append(" as ")
995-
writer.append(self.__alias)
995+
writer.append(QueryFieldUtil.escape_if_necessary(self.__alias))
996996

997997

998998
class VectorSearchToken(WhereToken):
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
Suggestions: display names containing spaces are quoted in the generated RQL.
3+
4+
C# reference: SlowTests/Issues/RavenDB_20673.cs
5+
CustomizeDisplayNameWithSpaces, CustomizeDisplayNameWithOutSpaces
6+
"""
7+
8+
from ravendb.documents.queries.suggestions import SuggestionBuilder
9+
from ravendb.tests.test_base import TestBase
10+
11+
12+
class User:
13+
def __init__(self, name: str = None):
14+
self.name = name
15+
16+
17+
class TestRavenDB20673(TestBase):
18+
def setUp(self):
19+
super().setUp()
20+
21+
def _setup_data(self):
22+
with self.store.open_session() as session:
23+
session.store(User(name="dan"), "users/1")
24+
session.store(User(name="daniel"), "users/2")
25+
session.store(User(name="danielle"), "users/3")
26+
session.save_changes()
27+
28+
self.wait_for_indexing(self.store)
29+
30+
def test_suggestion_display_name_without_spaces(self):
31+
"""Display names without spaces must work — baseline sanity check."""
32+
self._setup_data()
33+
34+
with self.store.open_session() as session:
35+
36+
def build(b: SuggestionBuilder):
37+
b.by_field("name", "daniele").with_display_name("CustomizedName")
38+
39+
suggestion_query = session.query(object_type=User).suggest_using(build)
40+
rql = suggestion_query.__str__()
41+
self.assertIn("CustomizedName", rql)
42+
43+
results = suggestion_query.execute()
44+
self.assertIn("CustomizedName", results)
45+
self.assertEqual(2, len(results["CustomizedName"].suggestions))
46+
self.assertIn("danielle", results["CustomizedName"].suggestions)
47+
48+
def test_suggestion_display_name_with_spaces(self):
49+
"""Display names containing spaces must be quoted in the RQL."""
50+
self._setup_data()
51+
52+
with self.store.open_session() as session:
53+
54+
def build(b: SuggestionBuilder):
55+
b.by_field("name", "daniele").with_display_name("Customized name with spaces")
56+
57+
suggestion_query = session.query(object_type=User).suggest_using(build)
58+
rql = suggestion_query.__str__()
59+
# escape_if_necessary wraps aliases containing spaces in single quotes
60+
self.assertIn("'Customized name with spaces'", rql)
61+
62+
results = suggestion_query.execute()
63+
self.assertIn("Customized name with spaces", results)
64+
self.assertEqual(2, len(results["Customized name with spaces"].suggestions))
65+
self.assertIn("danielle", results["Customized name with spaces"].suggestions)

0 commit comments

Comments
 (0)