Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
### unreleased

- fix: #99 fix update value containing "where" cause exception.

### 1.3.0

- fix: #93 last_executed_query() when params is a mapping of values.
- feature: #95 upgrade dependencies.

### 1.2.0

- feat: #72 support window functions.
Expand Down
4 changes: 2 additions & 2 deletions clickhouse_backend/backend/introspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
TableInfo = namedtuple("TableInfo", BaseTableInfo._fields + ("comment",))

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


Expand Down
27 changes: 18 additions & 9 deletions clickhouse_backend/driver/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
from .escape import escape_params
from .pool import ClickhousePool

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


def send_query(self, query, query_id=None, params=None):
Expand Down Expand Up @@ -100,11 +100,20 @@ def execute(self, operation, parameters=None):
query = self._client.substitute_params(
operation, parameters, self._client.connection.context
)
table, where = update_pattern.match(query).groups()
super().execute(f"select count(*) from {table} where {where}")
(rowcount,) = self.fetchone()
self._reset_state()
self._rowcount = rowcount
m = update_pattern.match(query)
table = m.group(1)
query_upper = query.upper()
i = query_upper.rfind(" WHERE ")
if i > 0:
j = query_upper.rfind(" SETTINGS ", i + 7)
if j > 0:
where = query[i + 7 : j]
else:
where = query[i + 7 :]
super().execute(f"select count(*) from {table} where {where}")
(rowcount,) = self.fetchone()
self._reset_state()
self._rowcount = rowcount
super().execute(operation, parameters)


Expand Down
7 changes: 7 additions & 0 deletions tests/queries/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,10 @@ def test_update(self):
self.a1.save()
with self.assertRaises(models.Author.MultipleObjectsReturned):
self.a1.refresh_from_db()

# regression test for https://github.com/jayvynl/django-clickhouse-backend/issues/99
def test_update_special_string_val(self):
self.a1.name = "where **"
self.a1.save()
self.a1.refresh_from_db()
self.assertEqual(self.a1.name, "where **")