diff --git a/src/connector/python/taos/bind.py b/src/connector/python/taos/bind.py index ede6381628ae0fd5ff8794ef23db2f5afcfb5f3d..2628a641f1ced3ecd51172a277cbd1ce398b2533 100644 --- a/src/connector/python/taos/bind.py +++ b/src/connector/python/taos/bind.py @@ -10,7 +10,8 @@ import sys _datetime_epoch = datetime.utcfromtimestamp(0) def _is_not_none(obj): - obj != None + return obj != None + class TaosBind(ctypes.Structure): _fields_ = [ ("buffer_type", c_int), @@ -320,6 +321,14 @@ class TaosMultiBind(ctypes.Structure): def nchar(self, values): # type: (list[str]) -> None + self.num = len(values) + self.buffer_type = FieldType.C_NCHAR + is_null = [1 if v == None else 0 for v in values] + self.is_null = cast((c_byte * self.num)(*is_null), c_char_p) + + if sum(is_null) == self.num: + self.length = (c_int32 * len(values))(0 * self.num) + return if sys.version_info < (3, 0): _bytes = [bytes(value) if value is not None else None for value in values] buffer_length = max(len(b) + 1 for b in _bytes if b is not None) @@ -347,9 +356,6 @@ class TaosMultiBind(ctypes.Structure): ) self.length = (c_int32 * len(values))(*[len(b) if b is not None else 0 for b in _bytes]) self.buffer_length = buffer_length - self.num = len(values) - self.is_null = cast((c_byte * self.num)(*[1 if v == None else 0 for v in values]), c_char_p) - self.buffer_type = FieldType.C_NCHAR def tinyint_unsigned(self, values): self.buffer_type = FieldType.C_TINYINT_UNSIGNED diff --git a/src/connector/python/tests/test-td6231.py b/src/connector/python/tests/test-td6231.py new file mode 100644 index 0000000000000000000000000000000000000000..e55d22c10734eedcbd5be8012eaeb3fb3d51e381 --- /dev/null +++ b/src/connector/python/tests/test-td6231.py @@ -0,0 +1,50 @@ +from taos import * + +conn = connect() + +dbname = "pytest_taos_stmt_multi" +conn.execute("drop database if exists %s" % dbname) +conn.execute("create database if not exists %s" % dbname) +conn.select_db(dbname) + +conn.execute( + "create table if not exists log(ts timestamp, bo bool, nil tinyint, \ + ti tinyint, si smallint, ii int, bi bigint, tu tinyint unsigned, \ + su smallint unsigned, iu int unsigned, bu bigint unsigned, \ + ff float, dd double, bb binary(100), nn nchar(100), tt timestamp)", +) + +stmt = conn.statement("insert into log values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)") + +params = new_multi_binds(16) +params[0].timestamp((1626861392589, 1626861392590, 1626861392591)) +params[1].bool((True, None, False)) +params[2].tinyint([-128, -128, None]) # -128 is tinyint null +params[3].tinyint([0, 127, None]) +params[4].smallint([3, None, 2]) +params[5].int([3, 4, None]) +params[6].bigint([3, 4, None]) +params[7].tinyint_unsigned([3, 4, None]) +params[8].smallint_unsigned([3, 4, None]) +params[9].int_unsigned([3, 4, None]) +params[10].bigint_unsigned([3, 4, None]) +params[11].float([3, None, 1]) +params[12].double([3, None, 1.2]) +params[13].binary(["abc", "dddafadfadfadfadfa", None]) +# params[14].nchar(["涛思数据", None, "a long string with 中文字符"]) +params[14].nchar([None, None, None]) +params[15].timestamp([None, None, 1626861392591]) +stmt.bind_param_batch(params) +stmt.execute() + + +result = stmt.use_result() +assert result.affected_rows == 3 +result.close() + +result = conn.query("select * from log") +for row in result: + print(row) +result.close() +stmt.close() +conn.close()