Skip to content

Commit 82fcf14

Browse files
committed
fix: fix update value containing "where" cause exception
1 parent 8621b49 commit 82fcf14

File tree

4 files changed

+36
-11
lines changed

4 files changed

+36
-11
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
### unreleased
2+
3+
- fix: #99 fix update value containing "where" cause exception.
4+
5+
### 1.3.0
6+
7+
- fix: #93 last_executed_query() when params is a mapping of values.
8+
- feature: #95 upgrade dependencies.
9+
110
### 1.2.0
211

312
- feat: #72 support window functions.

clickhouse_backend/backend/introspection.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
TableInfo = namedtuple("TableInfo", BaseTableInfo._fields + ("comment",))
1313

1414
constraint_pattern = re.compile(
15-
r"CONSTRAINT (`)?((?(1)(?:[^\\`]|\\.)+|\S+))(?(1)`|) (CHECK .+?),?\n"
15+
r"CONSTRAINT (`)?((?(1)(?:\\.|[^`])+|\S+))(?(1)`|) (CHECK .+?),?\n"
1616
)
1717
index_pattern = re.compile(
18-
r"INDEX (`)?((?(1)(?:[^\\`]|\\.)+|\S+))(?(1)`|) (.+? TYPE ([a-zA-Z_][0-9a-zA-Z_]*)\(.+?\) GRANULARITY \d+)"
18+
r"INDEX (`)?((?(1)(?:\\.|[^`])+|\S+))(?(1)`|) (.+? TYPE ([a-zA-Z_][0-9a-zA-Z_]*)\(.+?\) GRANULARITY \d+)"
1919
)
2020

2121

clickhouse_backend/driver/connection.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
from .escape import escape_params
1111
from .pool import ClickhousePool
1212

13-
update_pattern = re.compile(
14-
r"^\s*alter\s+table\s+(\S+)\s+.*?update.+?where\s+(.+?)(?:settings\s+.+)?$",
15-
flags=re.IGNORECASE,
16-
)
13+
name_regex = r'"(?:[^"]|\\.)+"'
14+
value_regex = r"(')?(?(1)(?:[^']|\\.)+|\S+)(?(1)'|)"
15+
name_value_regex = f"{name_regex} = {value_regex}"
16+
update_pattern = re.compile(f"^ALTER TABLE ({name_regex}) UPDATE ")
1717

1818

1919
def send_query(self, query, query_id=None, params=None):
@@ -100,11 +100,20 @@ def execute(self, operation, parameters=None):
100100
query = self._client.substitute_params(
101101
operation, parameters, self._client.connection.context
102102
)
103-
table, where = update_pattern.match(query).groups()
104-
super().execute(f"select count(*) from {table} where {where}")
105-
(rowcount,) = self.fetchone()
106-
self._reset_state()
107-
self._rowcount = rowcount
103+
m = update_pattern.match(query)
104+
table = m.group(1)
105+
query_upper = query.upper()
106+
i = query_upper.rfind(" WHERE ")
107+
if i > 0:
108+
j = query_upper.rfind(" SETTINGS ", i + 7)
109+
if j > 0:
110+
where = query[i + 7 : j]
111+
else:
112+
where = query[i + 7 :]
113+
super().execute(f"select count(*) from {table} where {where}")
114+
(rowcount,) = self.fetchone()
115+
self._reset_state()
116+
self._rowcount = rowcount
108117
super().execute(operation, parameters)
109118

110119

tests/queries/tests.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,10 @@ def test_update(self):
2020
self.a1.save()
2121
with self.assertRaises(models.Author.MultipleObjectsReturned):
2222
self.a1.refresh_from_db()
23+
24+
# regression test for https://github.com/jayvynl/django-clickhouse-backend/issues/99
25+
def test_update_special_string_val(self):
26+
self.a1.name = "where **"
27+
self.a1.save()
28+
self.a1.refresh_from_db()
29+
self.assertEqual(self.a1.name, "where **")

0 commit comments

Comments
 (0)