mirror of
https://github.com/hanzo-ds/connect.git
synced 2026-10-30 20:31:24 +00:00
Imports read `datastore_connect`, distribution `datastore-connect`, so nothing has to import another product's name to talk to Hanzo Datastore. Cut from upstream 0.8.17 — the version this stack already ran — rather than from upstream HEAD, so it is a PURE RENAME with no behaviour change. Forking from HEAD would have dragged versions along with the name (connect alone jumped 0.8.17 -> 1.6.0, a major), which is a different and much riskier change wearing a rename's clothes. X-ClickHouse-* headers are untouched: they are wire protocol the server sends and expects, and a different token shape from the module name.
155 lines
5.0 KiB
Python
155 lines
5.0 KiB
Python
from datastore_connect.driver.exceptions import ProgrammingError
|
|
|
|
from datastore_connect.datatypes.registry import get_from_name
|
|
from tests.helpers import to_bytes, native_insert_block
|
|
from tests.unit_tests.test_driver.binary import NESTED_BINARY
|
|
|
|
LOW_CARD_OUTPUT = """
|
|
0101 0576 616c 7565 204c 6f77 4361 7264
|
|
696e 616c 6974 7928 4e75 6c6c 6162 6c65
|
|
2853 7472 696e 6729 2901 0000 0000 0000
|
|
0000 0600 0000 0000 0002 0000 0000 0000
|
|
0000 0574 6872 6565 0100 0000 0000 0000
|
|
01
|
|
"""
|
|
|
|
TUPLE_ONE_OUTPUT = """
|
|
0101 0576 616c 7565 3854 7570 6c65 2853
|
|
7472 696e 672c 2046 6c6f 6174 3332 2c20
|
|
4c6f 7743 6172 6469 6e61 6c69 7479 284e
|
|
756c 6c61 626c 6528 5374 7269 6e67 2929
|
|
2901 0000 0000 0000 0007 7374 7269 6e67
|
|
317b 144e 4000 0600 0000 0000 0001 0000
|
|
0000 0000 0000 0100 0000 0000 0000 00
|
|
"""
|
|
|
|
TUPLE_THREE_OUTPUT = """
|
|
0103 0576 616c 7565 0d54 7570 6c65 2853
|
|
7472 696e 6729 0773 7472 696e 6731 0773
|
|
7472 696e 6732 0773 7472 696e 6733
|
|
"""
|
|
|
|
POINT_OUTPUT = """
|
|
0101 0576 616c 7565 0550 6f69 6e74 c3f5
|
|
285c 8fc2 0940 c3f5 285c 8fc2 0940
|
|
"""
|
|
|
|
STRING_ACCEPTS_BYTES_OUTPUT = """
|
|
0101 0576 616c 7565 0653 7472 696e 6701
|
|
ff
|
|
"""
|
|
|
|
MAP_LOW_CARDINALITY_OUTPUT = """
|
|
0102 034D 4150 234D 6170 284C 6F77 4361
|
|
7264 696E 616C 6974 7928 5374 7269 6E67
|
|
292C 2053 7472 696E 6729 0100 0000 0000
|
|
0000 0200 0000 0000 0000 0200 0000 0000
|
|
0000 0006 0000 0000 0000 0200 0000 0000
|
|
0000 046B 6579 3104 6B65 7932 0200 0000
|
|
0000 0000 0001 0131 0374 776F
|
|
"""
|
|
|
|
LOW_CARDINALITY_NULLABLE_OUTPUT = """
|
|
0102 0373 7472 204C 6F77 4361 7264 696E
|
|
616C 6974 7928 4E75 6C6C 6162 6C65 2853
|
|
7472 696E 6729 2901 0000 0000 0000 0000
|
|
0600 0000 0000 0002 0000 0000 0000 0000
|
|
0566 6972 7374 0200 0000 0000 0000 0100
|
|
"""
|
|
|
|
|
|
def test_low_card_null():
|
|
data = [['three']]
|
|
names = ['value']
|
|
types = [get_from_name('LowCardinality(Nullable(String))')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == to_bytes(LOW_CARD_OUTPUT)
|
|
|
|
|
|
def test_tuple_one():
|
|
data = [[('string1', 3.22, None)]]
|
|
names = ['value']
|
|
types = [get_from_name('Tuple(String, Float32, LowCardinality(Nullable(String)))')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == bytes.fromhex(TUPLE_ONE_OUTPUT)
|
|
|
|
|
|
def test_tuple_three():
|
|
data = [[('string1',)], [('string2',)], [('string3',)]]
|
|
names = ['value']
|
|
types = [get_from_name('Tuple(String)')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == bytes.fromhex(TUPLE_THREE_OUTPUT)
|
|
|
|
|
|
def test_point():
|
|
data = [[(3.22, 3.22)]]
|
|
names = ['value']
|
|
types = [get_from_name('Point')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == bytes.fromhex(POINT_OUTPUT)
|
|
|
|
|
|
def test_nested():
|
|
data = [([],),
|
|
([{'str1': 'three', 'int32': 5}, {'str1': 'five', 'int32': 77}],),
|
|
([{'str1': 'one', 'int32': 5}, {'str1': 'two', 'int32': 55}],),
|
|
([{'str1': 'one', 'int32': 5}, {'str1': 'two', 'int32': 55}],)]
|
|
types = [get_from_name('Nested(str1 String, int32 UInt32)')]
|
|
output = native_insert_block(data, ['nested'], types)
|
|
assert bytes(output) == bytes.fromhex(NESTED_BINARY)
|
|
|
|
|
|
def test_string_accepts_bytes():
|
|
data = [[bytes.fromhex('ff')]]
|
|
names = ['value']
|
|
types = [get_from_name('String')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == bytes.fromhex(STRING_ACCEPTS_BYTES_OUTPUT)
|
|
|
|
|
|
def test_long_str():
|
|
x = ('蹝ㅝDž잍鞏≈ﬞ㉢嫩杻⤧㛕錍к❭䦳텶샖爤㍅䱃䰅ἐ䤖엋㰾멛蹒뀃쩷섡፳聣᮵峧쒝咋觀હ鷁䯕͢퐠㏈猡칆빃밥뜼৫葘鹯勲掾ᬗ罧炼䏦險ヤⴕ懺릨봟죩ᬨ칰ԁ凢' +
|
|
'䰚娞祃獿휢듕鞜甲뉛⠆ᗫ䐼詠圂ᱞ出裒ਗ਼ᩜ㉤扷ꑐ晏镄焬㞧ノⷶ枆侪㇉摨⒞펦埏穊僛䦃吹ꗣ麥䔲鸈麡┨࣓ꢫႮstᝢ妢曢ꗠᆪ擽烣졀씥⣏便꽉슕盈㪃拪풻ᯖ럐峨' +
|
|
'箻躰䆲⏂錬횬渪㜟첯鋘ꊩ㾝톶╁茒牾붮뚂О灪噚놾蠂쌇龥䁼')
|
|
data = [[x]]
|
|
names = ['value']
|
|
types = [get_from_name('String')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == b'\x01\x01\x05value\x06String\xe7\x03' + x.encode()
|
|
|
|
|
|
def test_low_card_map():
|
|
data = [[{'key1': '1', 'key2': 'two'}], [{}]]
|
|
names = ['MAP']
|
|
types = [get_from_name('Map(LowCardinality(String), String)')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == bytes.fromhex(MAP_LOW_CARDINALITY_OUTPUT)
|
|
|
|
|
|
def test_low_card_nullable():
|
|
data = [['first'], [None]]
|
|
names = ['str']
|
|
types = [get_from_name('LowCardinality(Nullable(String))')]
|
|
output = native_insert_block(data, names, types)
|
|
assert bytes(output) == bytes.fromhex(LOW_CARDINALITY_NULLABLE_OUTPUT)
|
|
|
|
|
|
def test_bad_columns():
|
|
data = [['str'], [3.5]]
|
|
names = ['value']
|
|
types = [get_from_name('String')]
|
|
try:
|
|
native_insert_block(data, names, types)
|
|
except TypeError:
|
|
pass
|
|
|
|
data = [[3.5], [str]]
|
|
names = ['value']
|
|
types = [get_from_name('Float64')]
|
|
|
|
try:
|
|
native_insert_block(data, names, types)
|
|
except ProgrammingError:
|
|
pass
|