Skip to content

Commit dd301fd

Browse files
menshibinzitsenqevolg
authored
feat: native support blob type (#357) (#358)
* feat: native support blob type (#357) * feat: update rust connector version (#336) * feat: update rush connector versinon * feat(ws): upgrade rust connector --------- Co-authored-by: qevolg <2227465945@qq.com> * feat: add native blob type parse * feat: improve blob type test cases * feat: sql support blob type * feat: modify test case support blob * feat: stmt2 supports blob * feat: modify blob test case * feat: modify wokeflow TDengine branch main * feat: add log for query error * feat: modify blob test case for query error * feat: modify cheangelog format * feat: improve tmq test cases * feat: delete invalid comments --------- Co-authored-by: Linhe Huo <linhehuo@gmail.com> Co-authored-by: qevolg <2227465945@qq.com> * release: modify version to 2.8.3 * release: modify ci release sh --------- Co-authored-by: Linhe Huo <linhehuo@gmail.com> Co-authored-by: qevolg <2227465945@qq.com>
1 parent 66207f1 commit dd301fd

13 files changed

Lines changed: 190 additions & 44 deletions

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## v2.8.3 - 2025-07-24
11+
12+
### Features:
13+
14+
- native support blob type (#357)
15+
1016
## v2.8.2 - 2025-06-27
1117

1218
### Bug Fixes:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "taospy"
3-
version = "2.8.2"
3+
version = "2.8.3"
44
description = "The official TDengine Python connector"
55
authors = ["Taosdata Inc. <support@taosdata.com>"]
66
license = "MIT"

taos/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '2.8.2'
1+
__version__ = '2.8.3'

taos/bind2.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ def set_value(self, buffer_type, values, precision = PrecisionEnum.Milliseconds)
9191
self.varbinary(values)
9292
elif buffer_type == FieldType.C_GEOMETRY:
9393
self.geometry(values)
94+
elif buffer_type == FieldType.C_BLOB:
95+
self.blob(values)
9496

9597
def numeric_common(self, values, ctypes_type, buffer_null_type, buffer_value_type):
9698
if type(values) is not tuple and type(values) is not list:
@@ -218,6 +220,9 @@ def geometry(self, values):
218220
self.buffer_type = FieldType.C_GEOMETRY
219221
self._str_to_buffer(values, encode=False)
220222

223+
def blob(self, values):
224+
self.buffer_type = FieldType.C_BLOB
225+
self._str_to_buffer(values, encode=False)
221226

222227
class TaosStmt2BindV(ctypes.Structure):
223228
_fields_ = [

taos/cinterface.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ def taos_query(connection, sql):
328328
"""
329329
try:
330330
ptr = c_char_p(sql.encode("utf-8"))
331+
# if sql.lower().startswith("insert"):
332+
# raise ProgrammingError(sql, 1)
331333
res = c_void_p(_libtaos.taos_query(connection, ptr))
332334
errno = taos_errno(res)
333335
if errno != 0:
@@ -557,7 +559,7 @@ def taos_fetch_block_v3(result, fields=None, field_count=None, decode_binary=Tru
557559
raise DatabaseError("Invalid data type returned from database")
558560
offsets = []
559561
is_null = []
560-
if fields[i]["type"] in (FieldType.C_VARCHAR, FieldType.C_NCHAR, FieldType.C_JSON, FieldType.C_VARBINARY, FieldType.C_GEOMETRY):
562+
if fields[i]["type"] in (FieldType.C_VARCHAR, FieldType.C_NCHAR, FieldType.C_JSON, FieldType.C_VARBINARY, FieldType.C_GEOMETRY, FieldType.C_BLOB):
561563
offsets = taos_get_column_data_offset(result, i, num_of_rows)
562564
f = convert_block_func_v3(fields[i]["type"], decode_binary=decode_binary)
563565
blocks[i] = f(data, is_null, num_of_rows, offsets, precision)

taos/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class FieldType(object):
2929
C_JSON = 15
3030
C_VARBINARY = 16
3131
C_DECIMAL = 17
32+
C_BLOB = 18
3233
C_GEOMETRY = 20
3334
C_DECIMAL64 = 21
3435
# NULL value definition

taos/field.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,21 @@ def _crow_varbinary_to_python_block(data, is_null, num_of_rows, nbytes=None, pre
250250
res.append(cast(buffer, c_char_p).value)
251251
return res
252252

253+
def _crow_blob_to_python_block(data, is_null, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
254+
"""Function to convert C binary row to python row."""
255+
assert nbytes is not None
256+
res = []
257+
for i in range(abs(num_of_rows)):
258+
if is_null[i]:
259+
res.append(None)
260+
else:
261+
rbyte = ctypes.cast(data + nbytes * i, ctypes.POINTER(ctypes.c_uint16))[:1].pop()
262+
chars = ctypes.cast(c_char_p(data + nbytes * i + 4), ctypes.POINTER(c_char * rbyte))
263+
buffer = create_string_buffer(rbyte + 1)
264+
buffer[:rbyte] = chars[0][:rbyte]
265+
res.append(cast(buffer, c_char_p).value)
266+
return res
267+
253268

254269
def _crow_nchar_to_python_block(data, is_null, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
255270
"""Function to convert C nchar row to python row."""
@@ -301,6 +316,7 @@ def convert_block_func(field_type: FieldType, decode_binary=True):
301316
FieldType.C_GEOMETRY: _crow_varbinary_to_python,
302317
FieldType.C_DECIMAL: _crow_decimal_to_python,
303318
FieldType.C_DECIMAL64: _crow_decimal_to_python,
319+
FieldType.C_BLOB: _crow_blob_to_python_block,
304320
}
305321

306322
CONVERT_FUNC_BLOCK = {
@@ -323,6 +339,7 @@ def convert_block_func(field_type: FieldType, decode_binary=True):
323339
FieldType.C_GEOMETRY: _crow_varbinary_to_python_block,
324340
FieldType.C_DECIMAL: _crow_decimal_to_python,
325341
FieldType.C_DECIMAL64: _crow_decimal_to_python,
342+
FieldType.C_BLOB: _crow_blob_to_python_block,
326343
}
327344

328345

taos/field_v3.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
_RTYPE = ctypes.c_uint16
77
_RTYPE_SIZE = ctypes.sizeof(_RTYPE)
88

9+
_BLOB_RTYPE = ctypes.c_uint32
10+
_BLOB_RTYPE_SIZE = ctypes.sizeof(_BLOB_RTYPE)
911

1012
def _crow_binary_to_python_block_v3(data, is_null, num_of_rows, offsets, precision=FieldType.C_TIMESTAMP_UNKNOWN):
1113
"""Function to convert C binary row to python row."""
@@ -48,6 +50,18 @@ def _crow_varbinary_to_python_block_v3(data, is_null, num_of_rows, offsets, prec
4850
res.append(chars)
4951
return res
5052

53+
def _crow_blob_to_python_block_v3(data, is_null, num_of_rows, offsets, precision=FieldType.C_TIMESTAMP_UNKNOWN):
54+
"""Function to convert C varbinary row to python row."""
55+
assert offsets is not None
56+
res = []
57+
for i in range(abs(num_of_rows)):
58+
if offsets[i] == -1:
59+
res.append(None)
60+
else:
61+
rbyte = _RTYPE.from_address(data + offsets[i]).value
62+
chars = (ctypes.c_char * rbyte).from_address(data + offsets[i] + _BLOB_RTYPE_SIZE).raw
63+
res.append(chars)
64+
return res
5165

5266
def convert_block_func_v3(field_type: FieldType, decode_binary=True):
5367
"""Get convert block func."""
@@ -63,6 +77,7 @@ def convert_block_func_v3(field_type: FieldType, decode_binary=True):
6377
FieldType.C_JSON: _crow_nchar_to_python_block_v3,
6478
FieldType.C_VARBINARY: _crow_varbinary_to_python_block_v3,
6579
FieldType.C_GEOMETRY: _crow_varbinary_to_python_block_v3,
80+
FieldType.C_BLOB: _crow_blob_to_python_block_v3,
6681
}
6782

6883

taos/tmq.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def value(self):
125125

126126
block_data = ctypes.cast(block, ctypes.POINTER(ctypes.c_void_p))[i]
127127
if fields[i]["type"] in (
128-
FieldType.C_VARCHAR, FieldType.C_NCHAR, FieldType.C_JSON, FieldType.C_VARBINARY, FieldType.C_GEOMETRY):
128+
FieldType.C_VARCHAR, FieldType.C_NCHAR, FieldType.C_JSON, FieldType.C_VARBINARY, FieldType.C_GEOMETRY, FieldType.C_BLOB):
129129
f = convert_block_func_v3(fields[i]["type"], self.decode_binary)
130130
offsets = taos_get_column_data_offset(self.msg, i, num_rows)
131131
blocks[i] = f(block_data, [], num_rows, offsets, precision)

taos/utils.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,8 @@ def checkTypeValid(buffer_type, values):
195195
checkString("varbinary", values, [bytes, bytearray])
196196
elif buffer_type == FieldType.C_GEOMETRY:
197197
checkString("geometry", values, [bytes, bytearray])
198+
elif buffer_type == FieldType.C_BLOB:
199+
checkString("blob", values, [bytes, bytearray])
198200
else:
199201
err = f"invalid datatype type={buffer_type} values= {values}"
200202
raise DataTypeAndRangeError(err)

0 commit comments

Comments
 (0)