aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-11-22 10:17:54 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-11-22 11:04:40 +0300
commitc08cc1568cdccb1ee2404517a809c31b8601b5ac (patch)
tree73d1497b32a99a4574ff416a603fa9189df21509
parentc0ddd9a7b0bb0ab089b2483361389833efefa60c (diff)
downloadydb-c08cc1568cdccb1ee2404517a809c31b8601b5ac.tar.gz
Update contrib/python/clickhouse-connect to 0.6.19
-rw-r--r--contrib/python/clickhouse-connect/.dist-info/METADATA2
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/__version__.py2
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/dialect.py1
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/datatypes/container.py4
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/datatypes/string.py4
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/driver/dataconv.py7
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/driver/parser.py12
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py4
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/driverc/dataconv.pyx91
-rw-r--r--contrib/python/clickhouse-connect/clickhouse_connect/tools/testing.py6
-rw-r--r--contrib/python/clickhouse-connect/ya.make2
11 files changed, 73 insertions, 62 deletions
diff --git a/contrib/python/clickhouse-connect/.dist-info/METADATA b/contrib/python/clickhouse-connect/.dist-info/METADATA
index b078aa4b26..e7582522da 100644
--- a/contrib/python/clickhouse-connect/.dist-info/METADATA
+++ b/contrib/python/clickhouse-connect/.dist-info/METADATA
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: clickhouse-connect
-Version: 0.6.18
+Version: 0.6.19
Summary: ClickHouse Database Core Driver for Python, Pandas, and Superset
Home-page: https://github.com/ClickHouse/clickhouse-connect
Author: ClickHouse Inc.
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py b/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py
index 15ce74c8e3..3b0f77b522 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/__version__.py
@@ -1 +1 @@
-version = '0.6.18'
+version = '0.6.19'
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/dialect.py b/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/dialect.py
index 5eb1ed0113..6b04c7e2fe 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/dialect.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/cc_sqlalchemy/dialect.py
@@ -22,6 +22,7 @@ class ClickHouseDialect(DefaultDialect):
default_schema_name = 'default'
supports_native_decimal = True
supports_native_boolean = True
+ supports_statement_cache = False
returns_unicode_strings = True
postfetch_lastrowid = False
ddl_compiler = ChDDLCompiler
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/container.py b/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/container.py
index 0281867b8d..36e4c23780 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/container.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/container.py
@@ -3,7 +3,7 @@ import logging
from typing import Sequence, Collection
from clickhouse_connect.driver.insert import InsertContext
-from clickhouse_connect.driver.query import QueryContext
+from clickhouse_connect.driver.query import QueryContext, quote_identifier
from clickhouse_connect.driver.types import ByteSource
from clickhouse_connect.json_impl import any_to_json
from clickhouse_connect.datatypes.base import ClickHouseType, TypeDef
@@ -94,7 +94,7 @@ class Tuple(ClickHouseType):
self.element_names = type_def.keys
self.element_types = [get_from_name(name) for name in type_def.values]
if self.element_names:
- self._name_suffix = f"({', '.join(k + ' ' + str(v) for k, v in zip(type_def.keys, type_def.values))})"
+ self._name_suffix = f"({', '.join(quote_identifier(k) + ' ' + str(v) for k, v in zip(type_def.keys, type_def.values))})"
else:
self._name_suffix = type_def.arg_str
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/string.py b/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/string.py
index 7f6b7a5a77..0b5a81cbcb 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/string.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/datatypes/string.py
@@ -45,9 +45,9 @@ class String(ClickHouseType):
# pylint: disable=duplicate-code,too-many-nested-blocks,too-many-branches
def _write_column_binary(self, column: Union[Sequence, MutableSequence], dest: bytearray, ctx: InsertContext):
encoding = None
- if isinstance(self._first_value(column), str):
+ if not isinstance(self._first_value(column), bytes):
encoding = ctx.encoding or self.encoding
- data_conv.write_str_col(column, encoding, dest)
+ data_conv.write_str_col(column, self.nullable, encoding, dest)
def _active_null(self, ctx):
if ctx.use_none:
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/dataconv.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/dataconv.py
index 29c96a9a66..2427272572 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/dataconv.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/dataconv.py
@@ -5,6 +5,7 @@ from typing import Sequence, Optional, Any
from uuid import UUID, SafeUUID
from clickhouse_connect.driver.common import int_size
+from clickhouse_connect.driver.exceptions import DataError
from clickhouse_connect.driver.types import ByteSource
from clickhouse_connect.driver.options import np
@@ -110,14 +111,18 @@ def pivot(data: Sequence[Sequence], start_row: int, end_row: int) -> Sequence[Se
return tuple(zip(*data[start_row: end_row]))
-def write_str_col(column: Sequence, encoding: Optional[str], dest: bytearray):
+def write_str_col(column: Sequence, nullable: bool, encoding: Optional[str], dest: bytearray):
app = dest.append
for x in column:
if not x:
+ if not nullable and x is None:
+ raise DataError('Invalid None value in non-Nullable column')
app(0)
else:
if encoding:
x = x.encode(encoding)
+ else:
+ x = b''
sz = len(x)
while True:
b = sz & 0x7f
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/parser.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/parser.py
index a158e7f999..acdf9510e0 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/parser.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/parser.py
@@ -130,13 +130,13 @@ def parse_columns(expr: str):
named = False
level = 0
label = ''
- in_str = False
+ quote = None
while True:
char = expr[pos]
pos += 1
- if in_str:
- if "'" == char:
- in_str = False
+ if quote:
+ if char == quote:
+ quote = None
elif char == '\\' and expr[pos] == "'" and expr[pos:pos + 4] != "' = " and expr[pos:pos + 2] != "')":
label += expr[pos]
pos += 1
@@ -156,8 +156,8 @@ def parse_columns(expr: str):
elif char == ')':
columns.append(label)
break
- if char == "'" and (not label or 'Enum' in label):
- in_str = True
+ if char in ("'", '`') and (not label or 'Enum' in label):
+ quote = char
elif char == '(':
level += 1
elif char == ')':
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py b/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py
index 0b5086ae11..c4a48aafe0 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/driver/query.py
@@ -341,7 +341,7 @@ class QueryResult(Closable):
BS = '\\'
-must_escape = (BS, '\'')
+must_escape = (BS, '\'', '`')
def quote_identifier(identifier: str):
@@ -349,7 +349,7 @@ def quote_identifier(identifier: str):
if first_char in ('`', '"') and identifier[-1] == first_char:
# Identifier is already quoted, assume that it's valid
return identifier
- return f'`{identifier}`'
+ return f'`{escape_str(identifier)}`'
def finalize_query(query: str, parameters: Optional[Union[Sequence, Dict[str, Any]]],
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/driverc/dataconv.pyx b/contrib/python/clickhouse-connect/clickhouse_connect/driverc/dataconv.pyx
index dab9114155..0c9bbc19ae 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/driverc/dataconv.pyx
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/driverc/dataconv.pyx
@@ -19,6 +19,7 @@ from uuid import UUID, SafeUUID
from libc.string cimport memcpy
from datetime import tzinfo
+from clickhouse_connect.driver.exceptions import DataError
@cython.boundscheck(False)
@cython.wraparound(False)
@@ -254,7 +255,7 @@ cdef inline extend_byte_array(target: bytearray, int start, object source, Py_ss
@cython.boundscheck(False)
@cython.wraparound(False)
-def write_str_col(column: Sequence, encoding: Optional[str], dest: bytearray):
+def write_str_col(column: Sequence, nullable: bool, encoding: Optional[str], dest: bytearray):
cdef unsigned long long buff_size = len(column) << 5
cdef unsigned long long buff_loc = 0, sz = 0, dsz = 0
cdef unsigned long long array_size = PyByteArray_GET_SIZE(dest)
@@ -263,50 +264,54 @@ def write_str_col(column: Sequence, encoding: Optional[str], dest: bytearray):
cdef object encoded
cdef char b
cdef char * data
- for x in column:
- if not x:
- temp_buff[buff_loc] = 0
- buff_loc += 1
- if buff_loc == buff_size:
- extend_byte_array(dest, array_size, mv, buff_loc)
- array_size += buff_loc
- buff_loc = 0
- else:
- if not encoding:
- data = x
- dsz = len(x)
- else:
- encoded = x.encode(encoding)
- dsz = len(encoded)
- data = encoded
- sz = dsz
- while True:
- b = sz & 0x7f
- sz >>= 7
- if sz != 0:
- b |= 0x80
- temp_buff[buff_loc] = b
+ try:
+ for x in column:
+ if not x:
+ if not nullable and x is None:
+ raise DataError('Invalid None value in non-Nullable column')
+ temp_buff[buff_loc] = 0
buff_loc += 1
if buff_loc == buff_size:
extend_byte_array(dest, array_size, mv, buff_loc)
array_size += buff_loc
buff_loc = 0
- if sz == 0:
- break
- if dsz + buff_loc >= buff_size:
- if buff_loc > 0: # Write what we have so far
- extend_byte_array(dest, array_size, mv, buff_loc)
- array_size += buff_loc
- buff_loc = 0
- if (dsz << 4) > buff_size: # resize our buffer for very large strings
- PyMem_Free(<void *> temp_buff)
- mv.release()
- buff_size = dsz << 6
- temp_buff = <char *> PyMem_Malloc(<size_t> buff_size)
- mv = PyMemoryView_FromMemory(temp_buff, buff_size, PyBUF_READ)
- memcpy(temp_buff + buff_loc, data, dsz)
- buff_loc += dsz
- if buff_loc > 0:
- extend_byte_array(dest, array_size, mv, buff_loc)
- mv.release()
- PyMem_Free(<void *>temp_buff)
+ else:
+ if not encoding:
+ data = x
+ dsz = len(x)
+ else:
+ encoded = x.encode(encoding)
+ dsz = len(encoded)
+ data = encoded
+ sz = dsz
+ while True:
+ b = sz & 0x7f
+ sz >>= 7
+ if sz != 0:
+ b |= 0x80
+ temp_buff[buff_loc] = b
+ buff_loc += 1
+ if buff_loc == buff_size:
+ extend_byte_array(dest, array_size, mv, buff_loc)
+ array_size += buff_loc
+ buff_loc = 0
+ if sz == 0:
+ break
+ if dsz + buff_loc >= buff_size:
+ if buff_loc > 0: # Write what we have so far
+ extend_byte_array(dest, array_size, mv, buff_loc)
+ array_size += buff_loc
+ buff_loc = 0
+ if (dsz << 4) > buff_size: # resize our buffer for very large strings
+ PyMem_Free(<void *> temp_buff)
+ mv.release()
+ buff_size = dsz << 6
+ temp_buff = <char *> PyMem_Malloc(<size_t> buff_size)
+ mv = PyMemoryView_FromMemory(temp_buff, buff_size, PyBUF_READ)
+ memcpy(temp_buff + buff_loc, data, dsz)
+ buff_loc += dsz
+ if buff_loc > 0:
+ extend_byte_array(dest, array_size, mv, buff_loc)
+ finally:
+ mv.release()
+ PyMem_Free(<void *>temp_buff)
diff --git a/contrib/python/clickhouse-connect/clickhouse_connect/tools/testing.py b/contrib/python/clickhouse-connect/clickhouse_connect/tools/testing.py
index f30b3f754a..4351709610 100644
--- a/contrib/python/clickhouse-connect/clickhouse_connect/tools/testing.py
+++ b/contrib/python/clickhouse-connect/clickhouse_connect/tools/testing.py
@@ -1,7 +1,7 @@
from typing import Sequence, Optional, Union, Dict, Any
from clickhouse_connect.driver import Client
-from clickhouse_connect.driver.query import format_query_value
+from clickhouse_connect.driver.query import format_query_value, quote_identifier
class TableContext:
@@ -29,14 +29,14 @@ class TableContext:
self.column_names = columns
self.column_types = column_types
self.engine = engine
- self.order_by = self.column_names[0] if order_by is None else order_by
+ self.order_by = quote_identifier(self.column_names[0]) if order_by is None else order_by
def __enter__(self):
if self.client.min_version('19'):
self.client.command(f'DROP TABLE IF EXISTS {self.table}')
else:
self.client.command(f'DROP TABLE IF EXISTS {self.table} SYNC')
- col_defs = ','.join(f'{name} {col_type}' for name, col_type in zip(self.column_names, self.column_types))
+ col_defs = ','.join(f'{quote_identifier(name)} {col_type}' for name, col_type in zip(self.column_names, self.column_types))
create_cmd = f'CREATE TABLE {self.table} ({col_defs}) ENGINE {self.engine} ORDER BY {self.order_by}'
if self.settings:
create_cmd += ' SETTINGS '
diff --git a/contrib/python/clickhouse-connect/ya.make b/contrib/python/clickhouse-connect/ya.make
index db1563c6b8..b398d299cf 100644
--- a/contrib/python/clickhouse-connect/ya.make
+++ b/contrib/python/clickhouse-connect/ya.make
@@ -2,7 +2,7 @@
PY3_LIBRARY()
-VERSION(0.6.18)
+VERSION(0.6.19)
LICENSE(Apache-2.0)