chdb 3.3.0__cp311-cp311-macosx_11_0_arm64.whl → 3.4.1__cp311-cp311-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of chdb might be problematic. Click here for more details.
- chdb/__init__.py +1 -1
- chdb/_chdb.cpython-311-darwin.so +0 -0
- chdb/session/state.py +3 -15
- {chdb-3.3.0.dist-info → chdb-3.4.1.dist-info}/METADATA +1 -1
- {chdb-3.3.0.dist-info → chdb-3.4.1.dist-info}/RECORD +8 -10
- chdb/state/test_sqlitelike.py +0 -236
- chdb/tests/test_dbapi.py +0 -83
- {chdb-3.3.0.dist-info → chdb-3.4.1.dist-info}/WHEEL +0 -0
- {chdb-3.3.0.dist-info → chdb-3.4.1.dist-info}/licenses/LICENSE.txt +0 -0
- {chdb-3.3.0.dist-info → chdb-3.4.1.dist-info}/top_level.txt +0 -0
chdb/__init__.py
CHANGED
|
@@ -19,7 +19,7 @@ _process_result_format_funs = {
|
|
|
19
19
|
# UDF script path will be f"{g_udf_path}/{func_name}.py"
|
|
20
20
|
g_udf_path = ""
|
|
21
21
|
|
|
22
|
-
chdb_version = ('3', '
|
|
22
|
+
chdb_version = ('3', '4', '1')
|
|
23
23
|
if sys.version_info[:2] >= (3, 7):
|
|
24
24
|
# get the path of the current file
|
|
25
25
|
current_path = os.path.dirname(os.path.abspath(__file__))
|
chdb/_chdb.cpython-311-darwin.so
CHANGED
|
Binary file
|
chdb/session/state.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import tempfile
|
|
2
|
-
import shutil
|
|
3
1
|
import warnings
|
|
4
2
|
|
|
5
3
|
import chdb
|
|
@@ -51,11 +49,9 @@ class Session:
|
|
|
51
49
|
)
|
|
52
50
|
g_session.close()
|
|
53
51
|
g_session_path = None
|
|
54
|
-
if path is None
|
|
55
|
-
self.
|
|
56
|
-
self._path = tempfile.mkdtemp()
|
|
52
|
+
if path is None:
|
|
53
|
+
self._path = ":memory:"
|
|
57
54
|
else:
|
|
58
|
-
self._cleanup = False
|
|
59
55
|
self._path = path
|
|
60
56
|
if chdb.g_udf_path != "":
|
|
61
57
|
self._udf_path = chdb.g_udf_path
|
|
@@ -84,8 +80,6 @@ class Session:
|
|
|
84
80
|
self.close()
|
|
85
81
|
|
|
86
82
|
def close(self):
|
|
87
|
-
if self._cleanup:
|
|
88
|
-
self.cleanup()
|
|
89
83
|
if self._conn is not None:
|
|
90
84
|
self._conn.close()
|
|
91
85
|
self._conn = None
|
|
@@ -95,13 +89,7 @@ class Session:
|
|
|
95
89
|
|
|
96
90
|
def cleanup(self):
|
|
97
91
|
try:
|
|
98
|
-
|
|
99
|
-
self._conn.close()
|
|
100
|
-
self._conn = None
|
|
101
|
-
shutil.rmtree(self._path)
|
|
102
|
-
global g_session, g_session_path
|
|
103
|
-
g_session = None
|
|
104
|
-
g_session_path = None
|
|
92
|
+
self.close()
|
|
105
93
|
except: # noqa
|
|
106
94
|
pass
|
|
107
95
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
chdb/__init__.py,sha256=
|
|
1
|
+
chdb/__init__.py,sha256=KjR7cb7QFtjCqvasu81WQvX-2LeHjx-rSB3preiRefI,3762
|
|
2
2
|
chdb/__main__.py,sha256=xNNtDY38d973YM5dlxiIazcqqKhXJSpNb7JflyyrXGE,1185
|
|
3
|
-
chdb/_chdb.cpython-311-darwin.so,sha256=
|
|
3
|
+
chdb/_chdb.cpython-311-darwin.so,sha256=tS5H0vTnCxb9dCSG8aVXeEWVYZyXBi7Ir1TvguzdUVQ,383557888
|
|
4
4
|
chdb/rwabc.py,sha256=tbiwCrXirfrfx46wCJxS64yvFe6pVWIPGdSuvrAL5Ys,2102
|
|
5
5
|
chdb/dataframe/__init__.py,sha256=1_mrZZiJwqBTnH_P8_FCbbYXIWWY5sxnaFpe3-tDLF4,680
|
|
6
6
|
chdb/dataframe/query.py,sha256=ggvE8A5vtabFg9gSTp99S7LCrnIEwbWtb-PtJVT8Ct0,12759
|
|
@@ -13,18 +13,16 @@ chdb/dbapi/times.py,sha256=_qXgDaYwsHntvpIKSKXp1rrYIgtq6Z9pLyLnO2XNoL0,360
|
|
|
13
13
|
chdb/dbapi/constants/FIELD_TYPE.py,sha256=ytFzgAnGmb9hvdsBlnK68qdZv_a6jYFIXT6VSAb60z8,370
|
|
14
14
|
chdb/dbapi/constants/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
chdb/session/__init__.py,sha256=fCUROZ5L1-92o2lcASiWJpFu-80-kDoSrNfouLEmLg8,50
|
|
16
|
-
chdb/session/state.py,sha256=
|
|
16
|
+
chdb/session/state.py,sha256=m7K9zZtoMQTlh-pfmSyJV38pAe6eHNTPtOvlHYrImhA,4436
|
|
17
17
|
chdb/state/__init__.py,sha256=RVUIWDqDi7gte4Os7Mz1wPXFyFpdHT_p1klJC7QtluI,55
|
|
18
18
|
chdb/state/sqlitelike.py,sha256=v0xh9jWirHzhDVq26C2213LxfaDbRulSAhSHaTiZ24c,12283
|
|
19
|
-
chdb/state/test_sqlitelike.py,sha256=8Y7Up2Glkl6PpSgkMF_Rgz_3oGgx-6aLcyxaw2bzQR8,7586
|
|
20
|
-
chdb/tests/test_dbapi.py,sha256=Z5KloM0ujhVFaLOES6V6slLIRWbTyg0lPyggl3m2ZqY,2765
|
|
21
19
|
chdb/udf/__init__.py,sha256=qSMaPEre7w1pYz8uJ-iZtuu8wYOUNRcI_8UNuaOymGE,80
|
|
22
20
|
chdb/udf/udf.py,sha256=z0A1RmyZrx55bykpvvS-LpVt1lMrQOexjvU5zxCdCSA,3935
|
|
23
21
|
chdb/utils/__init__.py,sha256=tXRcwBRGW2YQNBZWV4Mitw5QlCu_qlSRCjllw15XHbs,171
|
|
24
22
|
chdb/utils/trace.py,sha256=W-pvDoKlnzq6H_7FiWjr5_teN40UNE4E5--zbUrjOIc,2511
|
|
25
23
|
chdb/utils/types.py,sha256=MGLFIjoDvu7Uc2Wy8EDY60jjue66HmMPxbhrujjrZxQ,7530
|
|
26
|
-
chdb-3.
|
|
27
|
-
chdb-3.
|
|
28
|
-
chdb-3.
|
|
29
|
-
chdb-3.
|
|
30
|
-
chdb-3.
|
|
24
|
+
chdb-3.4.1.dist-info/licenses/LICENSE.txt,sha256=isYVtNCO5910aj6e9bJJ6kQceivkLqsMlFSNYwzGGKI,11366
|
|
25
|
+
chdb-3.4.1.dist-info/METADATA,sha256=uFmfdxDkm0eBkLJcMsBKZdxjfRrPccIOjYHBxmPw2mQ,24690
|
|
26
|
+
chdb-3.4.1.dist-info/WHEEL,sha256=qxQkdhERtGxJzqnVOBnucx1aUmU2n3HmuzYdln_LyOw,109
|
|
27
|
+
chdb-3.4.1.dist-info/top_level.txt,sha256=se0Jj0A2-ijfMW51hIjiuNyDJPqy5xJU1G8a_IEdllI,11
|
|
28
|
+
chdb-3.4.1.dist-info/RECORD,,
|
chdb/state/test_sqlitelike.py
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from datetime import datetime, date
|
|
3
|
-
from chdb.state.sqlitelike import connect
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class TestCursor(unittest.TestCase):
|
|
7
|
-
def setUp(self):
|
|
8
|
-
self.conn = connect(":memory:")
|
|
9
|
-
self.cursor = self.conn.cursor()
|
|
10
|
-
|
|
11
|
-
def tearDown(self):
|
|
12
|
-
self.cursor.close()
|
|
13
|
-
self.conn.close()
|
|
14
|
-
|
|
15
|
-
def test_basic_types(self):
|
|
16
|
-
# Test basic types including NULL values
|
|
17
|
-
self.cursor.execute(
|
|
18
|
-
"""
|
|
19
|
-
SELECT
|
|
20
|
-
42 as int_val,
|
|
21
|
-
3.14 as float_val,
|
|
22
|
-
'hello' as str_val,
|
|
23
|
-
true as bool_val,
|
|
24
|
-
NULL as null_val
|
|
25
|
-
"""
|
|
26
|
-
)
|
|
27
|
-
row = self.cursor.fetchone()
|
|
28
|
-
self.assertEqual(row, (42, 3.14, "hello", True, None))
|
|
29
|
-
|
|
30
|
-
def test_date_time_types(self):
|
|
31
|
-
# Test date and datetime types with various formats
|
|
32
|
-
self.cursor.execute(
|
|
33
|
-
"""
|
|
34
|
-
SELECT
|
|
35
|
-
toDateTime('2024-03-20 15:30:00') as datetime_str,
|
|
36
|
-
toDateTime64('2024-03-20 15:30:00.123456', 6) as datetime64_str,
|
|
37
|
-
toDate('2024-03-20') as date_str,
|
|
38
|
-
toDateTime(1710945000) as datetime_ts, -- 2024-03-20 15:30:00
|
|
39
|
-
toDate(19437) as date_ts -- 2024-03-20 (days since 1970-01-01)
|
|
40
|
-
"""
|
|
41
|
-
)
|
|
42
|
-
row = self.cursor.fetchone()
|
|
43
|
-
self.assertEqual(len(row), 5)
|
|
44
|
-
|
|
45
|
-
# Test datetime string format
|
|
46
|
-
self.assertIsInstance(row[0], datetime)
|
|
47
|
-
self.assertEqual(row[0].strftime("%Y-%m-%d %H:%M:%S"), "2024-03-20 15:30:00")
|
|
48
|
-
|
|
49
|
-
# Test datetime64 with microseconds
|
|
50
|
-
self.assertIsInstance(row[1], datetime)
|
|
51
|
-
self.assertEqual(
|
|
52
|
-
row[1].strftime("%Y-%m-%d %H:%M:%S.%f"), "2024-03-20 15:30:00.123456"
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
# Test date string format
|
|
56
|
-
self.assertIsInstance(row[2], date)
|
|
57
|
-
self.assertEqual(row[2].isoformat(), "2024-03-20")
|
|
58
|
-
|
|
59
|
-
# Test datetime from timestamp
|
|
60
|
-
self.assertIsInstance(row[3], datetime)
|
|
61
|
-
self.assertEqual(row[3].strftime("%Y-%m-%d %H:%M:%S"), "2024-03-20 15:30:00")
|
|
62
|
-
|
|
63
|
-
# Test date from timestamp
|
|
64
|
-
self.assertIsInstance(row[4], date)
|
|
65
|
-
self.assertEqual(row[4].isoformat(), "2024-03-20")
|
|
66
|
-
|
|
67
|
-
def test_array_types(self):
|
|
68
|
-
# Test array types (should be converted to string)
|
|
69
|
-
self.cursor.execute(
|
|
70
|
-
"""
|
|
71
|
-
SELECT
|
|
72
|
-
[1, 2, 3] as int_array,
|
|
73
|
-
['a', 'b', 'c'] as str_array
|
|
74
|
-
"""
|
|
75
|
-
)
|
|
76
|
-
row = self.cursor.fetchone()
|
|
77
|
-
self.assertIsInstance(row[0], str)
|
|
78
|
-
self.assertIsInstance(row[1], str)
|
|
79
|
-
|
|
80
|
-
def test_complex_types(self):
|
|
81
|
-
# Test more complex ClickHouse types
|
|
82
|
-
self.cursor.execute(
|
|
83
|
-
"""
|
|
84
|
-
SELECT
|
|
85
|
-
toDecimal64(123.45, 2) as decimal_val,
|
|
86
|
-
toFixedString('test', 10) as fixed_str_val,
|
|
87
|
-
tuple(1, 'a') as tuple_val,
|
|
88
|
-
map('key', 'value') as map_val
|
|
89
|
-
"""
|
|
90
|
-
)
|
|
91
|
-
row = self.cursor.fetchone()
|
|
92
|
-
# All complex types should be converted to strings
|
|
93
|
-
for val in row:
|
|
94
|
-
self.assertIsInstance(val, (str, type(None)))
|
|
95
|
-
|
|
96
|
-
def test_fetch_methods(self):
|
|
97
|
-
# Test different fetch methods
|
|
98
|
-
self.cursor.execute(
|
|
99
|
-
"""
|
|
100
|
-
SELECT number
|
|
101
|
-
FROM system.numbers
|
|
102
|
-
LIMIT 5
|
|
103
|
-
"""
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
# Test fetchone
|
|
107
|
-
self.assertEqual(self.cursor.fetchone(), (0,))
|
|
108
|
-
|
|
109
|
-
# Test fetchmany
|
|
110
|
-
self.assertEqual(self.cursor.fetchmany(2), ((1,), (2,)))
|
|
111
|
-
|
|
112
|
-
# Test fetchall
|
|
113
|
-
self.assertEqual(self.cursor.fetchall(), ((3,), (4,)))
|
|
114
|
-
|
|
115
|
-
# Test fetchone after end
|
|
116
|
-
self.assertIsNone(self.cursor.fetchone())
|
|
117
|
-
|
|
118
|
-
def test_empty_result(self):
|
|
119
|
-
# Test empty result handling
|
|
120
|
-
self.cursor.execute("SELECT 1 WHERE 1=0")
|
|
121
|
-
self.assertIsNone(self.cursor.fetchone())
|
|
122
|
-
self.assertEqual(self.cursor.fetchall(), ())
|
|
123
|
-
|
|
124
|
-
def test_iterator(self):
|
|
125
|
-
# Test cursor as iterator
|
|
126
|
-
self.cursor.execute(
|
|
127
|
-
"""
|
|
128
|
-
SELECT number
|
|
129
|
-
FROM system.numbers
|
|
130
|
-
LIMIT 3
|
|
131
|
-
"""
|
|
132
|
-
)
|
|
133
|
-
rows = [row for row in self.cursor]
|
|
134
|
-
self.assertEqual(rows, [(0,), (1,), (2,)])
|
|
135
|
-
|
|
136
|
-
def test_error_handling(self):
|
|
137
|
-
# Test invalid SQL
|
|
138
|
-
with self.assertRaises(Exception):
|
|
139
|
-
self.cursor.execute("SELECT invalid_column")
|
|
140
|
-
|
|
141
|
-
def test_large_result(self):
|
|
142
|
-
# Test handling of larger result sets
|
|
143
|
-
self.cursor.execute(
|
|
144
|
-
"""
|
|
145
|
-
SELECT
|
|
146
|
-
number,
|
|
147
|
-
toString(number) as str_val,
|
|
148
|
-
toDateTime('2024-03-20 15:30:00') + interval number second as time_val
|
|
149
|
-
FROM system.numbers
|
|
150
|
-
LIMIT 1000
|
|
151
|
-
"""
|
|
152
|
-
)
|
|
153
|
-
rows = self.cursor.fetchall()
|
|
154
|
-
self.assertEqual(len(rows), 1000)
|
|
155
|
-
self.assertEqual(rows[0], (0, "0", datetime(2024, 3, 20, 15, 30, 0)))
|
|
156
|
-
self.assertEqual(rows[-1], (999, "999", datetime(2024, 3, 20, 15, 46, 39)))
|
|
157
|
-
|
|
158
|
-
def test_column_names(self):
|
|
159
|
-
# Test that column names are stored and accessible
|
|
160
|
-
self.cursor.execute(
|
|
161
|
-
"""
|
|
162
|
-
SELECT
|
|
163
|
-
42 as int_col,
|
|
164
|
-
'hello' as str_col,
|
|
165
|
-
now() as time_col
|
|
166
|
-
"""
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
# Test the column names method
|
|
170
|
-
self.assertEqual(self.cursor.column_names(), ["int_col", "str_col", "time_col"])
|
|
171
|
-
|
|
172
|
-
# Test the column types method
|
|
173
|
-
self.assertEqual(len(self.cursor.column_types()), 3)
|
|
174
|
-
|
|
175
|
-
# Test the description property (DB-API 2.0)
|
|
176
|
-
description = self.cursor.description
|
|
177
|
-
self.assertEqual(len(description), 3)
|
|
178
|
-
self.assertEqual(description[0][0], "int_col") # First column name
|
|
179
|
-
self.assertEqual(description[1][0], "str_col") # Second column name
|
|
180
|
-
|
|
181
|
-
# Test fetchone
|
|
182
|
-
row = self.cursor.fetchone()
|
|
183
|
-
self.assertEqual(len(row), 3)
|
|
184
|
-
|
|
185
|
-
# Test that all data was properly converted
|
|
186
|
-
self.assertIsInstance(row[0], int)
|
|
187
|
-
self.assertIsInstance(row[1], str)
|
|
188
|
-
self.assertIsInstance(
|
|
189
|
-
row[2], (str, datetime)
|
|
190
|
-
) # May be str or datetime depending on conversion
|
|
191
|
-
|
|
192
|
-
def test_uuid_type(self):
|
|
193
|
-
# Test UUID type handling
|
|
194
|
-
self.cursor.execute(
|
|
195
|
-
"SELECT '6bbd51ac-b0cc-43a2-8cb2-eab06ff7de7b'::UUID as uuid_val"
|
|
196
|
-
)
|
|
197
|
-
row = self.cursor.fetchone()
|
|
198
|
-
self.assertEqual(row[0], "6bbd51ac-b0cc-43a2-8cb2-eab06ff7de7b")
|
|
199
|
-
|
|
200
|
-
# Test UUID in a more complex query
|
|
201
|
-
self.cursor.execute(
|
|
202
|
-
"""
|
|
203
|
-
SELECT
|
|
204
|
-
'6bbd51ac-b0cc-43a2-8cb2-eab06ff7de7b'::UUID as uuid_val1,
|
|
205
|
-
NULL::UUID as uuid_val2
|
|
206
|
-
"""
|
|
207
|
-
)
|
|
208
|
-
row = self.cursor.fetchone()
|
|
209
|
-
self.assertEqual(row[0], "6bbd51ac-b0cc-43a2-8cb2-eab06ff7de7b")
|
|
210
|
-
self.assertIsNone(row[1])
|
|
211
|
-
|
|
212
|
-
def test_null_handling(self):
|
|
213
|
-
# Test NULL handling
|
|
214
|
-
self.cursor.execute("SELECT NULL")
|
|
215
|
-
row = self.cursor.fetchone()
|
|
216
|
-
self.assertEqual(row, (None,))
|
|
217
|
-
|
|
218
|
-
# Test NULL with different types
|
|
219
|
-
self.cursor.execute(
|
|
220
|
-
"""
|
|
221
|
-
SELECT
|
|
222
|
-
NULL::Int32 as null_int,
|
|
223
|
-
NULL::String as null_str,
|
|
224
|
-
NULL::UUID as null_uuid,
|
|
225
|
-
NULL::DateTime as null_datetime,
|
|
226
|
-
NULL::Date as null_date
|
|
227
|
-
"""
|
|
228
|
-
)
|
|
229
|
-
row = self.cursor.fetchone()
|
|
230
|
-
self.assertEqual(len(row), 5)
|
|
231
|
-
for val in row:
|
|
232
|
-
self.assertIsNone(val)
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if __name__ == "__main__":
|
|
236
|
-
unittest.main()
|
chdb/tests/test_dbapi.py
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from chdb.dbapi import connect
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class TestDBAPI(unittest.TestCase):
|
|
6
|
-
def setUp(self):
|
|
7
|
-
self.conn = connect()
|
|
8
|
-
self.cur = self.conn.cursor()
|
|
9
|
-
|
|
10
|
-
def tearDown(self):
|
|
11
|
-
self.cur.close()
|
|
12
|
-
self.conn.close()
|
|
13
|
-
|
|
14
|
-
def test_select_version(self):
|
|
15
|
-
"""Test simple version query"""
|
|
16
|
-
self.cur.execute("select version()") # ClickHouse version
|
|
17
|
-
row = self.cur.fetchone()
|
|
18
|
-
self.assertIsNotNone(row)
|
|
19
|
-
self.assertEqual(len(row), 1)
|
|
20
|
-
self.assertIsInstance(row[0], str)
|
|
21
|
-
|
|
22
|
-
def test_description(self):
|
|
23
|
-
"""Test cursor description"""
|
|
24
|
-
# Test with multiple columns of different types
|
|
25
|
-
self.cur.execute(
|
|
26
|
-
"""
|
|
27
|
-
SELECT
|
|
28
|
-
1 as int_col,
|
|
29
|
-
'test' as str_col,
|
|
30
|
-
now() as time_col,
|
|
31
|
-
NULL as null_col,
|
|
32
|
-
'6bbd51ac-b0cc-43a2-8cb2-eab06ff7de7b'::UUID as uuid_col
|
|
33
|
-
"""
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
# Check description format
|
|
37
|
-
self.assertIsNotNone(self.cur.description)
|
|
38
|
-
self.assertEqual(len(self.cur.description), 5)
|
|
39
|
-
|
|
40
|
-
# Check each column's metadata
|
|
41
|
-
int_col = self.cur.description[0]
|
|
42
|
-
str_col = self.cur.description[1]
|
|
43
|
-
time_col = self.cur.description[2]
|
|
44
|
-
null_col = self.cur.description[3]
|
|
45
|
-
uuid_col = self.cur.description[4]
|
|
46
|
-
|
|
47
|
-
# Check column names
|
|
48
|
-
self.assertEqual(int_col[0], "int_col")
|
|
49
|
-
self.assertEqual(str_col[0], "str_col")
|
|
50
|
-
self.assertEqual(time_col[0], "time_col")
|
|
51
|
-
self.assertEqual(null_col[0], "null_col")
|
|
52
|
-
self.assertEqual(uuid_col[0], "uuid_col")
|
|
53
|
-
|
|
54
|
-
# Check that type info is present
|
|
55
|
-
self.assertTrue(int_col[1].startswith("Int") or int_col[1].startswith("UInt"))
|
|
56
|
-
self.assertTrue(str_col[1] in ("String", "FixedString"))
|
|
57
|
-
self.assertTrue(time_col[1].startswith("DateTime"))
|
|
58
|
-
self.assertTrue(uuid_col[1] == "UUID")
|
|
59
|
-
|
|
60
|
-
# Check that other fields are None as per DB-API 2.0
|
|
61
|
-
for col in self.cur.description:
|
|
62
|
-
self.assertEqual(len(col), 7) # DB-API 2.0 specifies 7 fields
|
|
63
|
-
self.assertTrue(
|
|
64
|
-
all(x is None for x in col[2:])
|
|
65
|
-
) # All fields after name and type should be None
|
|
66
|
-
|
|
67
|
-
def test_rowcount(self):
|
|
68
|
-
"""Test rowcount attribute"""
|
|
69
|
-
# Test with empty result
|
|
70
|
-
self.cur.execute("SELECT 1 WHERE 1=0")
|
|
71
|
-
self.assertEqual(self.cur.rowcount, 0)
|
|
72
|
-
|
|
73
|
-
# Test with single row
|
|
74
|
-
self.cur.execute("SELECT 1")
|
|
75
|
-
self.assertEqual(self.cur.rowcount, 1)
|
|
76
|
-
|
|
77
|
-
# Test with multiple rows
|
|
78
|
-
self.cur.execute("SELECT number FROM system.numbers LIMIT 10")
|
|
79
|
-
self.assertEqual(self.cur.rowcount, 10)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if __name__ == "__main__":
|
|
83
|
-
unittest.main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|