tinybird-toolset 2.5.0__tar.gz → 2.5.4__tar.gz
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.
- {tinybird_toolset-2.5.0/src/tinybird_toolset.egg-info → tinybird_toolset-2.5.4}/PKG-INFO +1 -1
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/setup.py +17 -21
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4/src/tinybird_toolset.egg-info}/PKG-INFO +1 -1
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_convert_to_row_binary.py +64 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_tables.py +1 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_validate_ttl.py +42 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/LICENSE +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/MANIFEST.in +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/README.md +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/conf.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/setup.cfg +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/chtoolset/__init__.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/chtoolset/query.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/SOURCES.txt +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/dependency_links.txt +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/requires.txt +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/top_level.txt +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_check_compatible_types.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_check_write_query.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_chquery.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_explain_ast.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_get_columns_from_create_query.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_get_left_table.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_internal_cache.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_normalize_query_keep_names.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_normalize_table_column.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_parse_create_materialized_view_target_table.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_replace_tables.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_replace_tables_backward_compat.py +0 -0
- {tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_rewrite_aggregation_states.py +0 -0
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
from setuptools import setup, Extension
|
|
2
2
|
|
|
3
3
|
NAME = 'tinybird-toolset'
|
|
4
|
-
VERSION = '2.5.
|
|
4
|
+
VERSION = '2.5.4'
|
|
5
|
+
|
|
6
|
+
# Shared metadata for both the full (extension) build and the metadata-only
|
|
7
|
+
# fallback below, so the two setup() calls can't drift apart.
|
|
8
|
+
common_kwargs = dict(
|
|
9
|
+
name=NAME,
|
|
10
|
+
version=VERSION,
|
|
11
|
+
url="https://gitlab.com/tinybird/clickhouse-toolset",
|
|
12
|
+
author="Tinybird.co",
|
|
13
|
+
author_email="support@tinybird.co",
|
|
14
|
+
packages=["chtoolset"],
|
|
15
|
+
package_dir={"": "src"},
|
|
16
|
+
python_requires=">=3.10, <3.15",
|
|
17
|
+
install_requires=[],
|
|
18
|
+
)
|
|
5
19
|
|
|
6
20
|
try:
|
|
7
21
|
from conf import *
|
|
@@ -32,15 +46,7 @@ try:
|
|
|
32
46
|
],
|
|
33
47
|
)
|
|
34
48
|
setup(
|
|
35
|
-
|
|
36
|
-
version=VERSION,
|
|
37
|
-
url="https://gitlab.com/tinybird/clickhouse-toolset",
|
|
38
|
-
author="Tinybird.co",
|
|
39
|
-
author_email="support@tinybird.co",
|
|
40
|
-
packages=["chtoolset"],
|
|
41
|
-
package_dir={"": "src"},
|
|
42
|
-
python_requires=">=3.10, <3.15",
|
|
43
|
-
install_requires=[],
|
|
49
|
+
**common_kwargs,
|
|
44
50
|
extras_require={"test": requirements_from_file("requirements-test.txt")},
|
|
45
51
|
cmdclass={
|
|
46
52
|
"clickhouse": ClickHouseBuildExt,
|
|
@@ -51,14 +57,4 @@ try:
|
|
|
51
57
|
)
|
|
52
58
|
|
|
53
59
|
except ModuleNotFoundError:
|
|
54
|
-
setup(
|
|
55
|
-
name=NAME,
|
|
56
|
-
version=VERSION,
|
|
57
|
-
url="https://gitlab.com/tinybird/clickhouse-toolset",
|
|
58
|
-
author="Tinybird.co",
|
|
59
|
-
author_email="support@tinybird.co",
|
|
60
|
-
packages=["chtoolset"],
|
|
61
|
-
package_dir={"": "src"},
|
|
62
|
-
python_requires=">=3.10, <3.15",
|
|
63
|
-
install_requires=[],
|
|
64
|
-
)
|
|
60
|
+
setup(**common_kwargs)
|
|
@@ -8467,6 +8467,70 @@ TEST_CASES = [
|
|
|
8467
8467
|
|
|
8468
8468
|
|
|
8469
8469
|
class TestRowBinaryEncoder:
|
|
8470
|
+
@pytest.mark.parametrize("legacy_conversion_mode", [True, False])
|
|
8471
|
+
def test_convert_ipv4_to_row_binary(self, legacy_conversion_mode):
|
|
8472
|
+
schema = json.dumps(get_schema([('address', 'IPv4', '$.address', False)]))
|
|
8473
|
+
|
|
8474
|
+
with chquery.RowBinaryEncoder(schema, legacy_conversion_mode=legacy_conversion_mode) as encoder:
|
|
8475
|
+
result, quarantine, nrows, nquarantine = encoder.encode('{"address": "192.0.2.1"}')
|
|
8476
|
+
|
|
8477
|
+
assert result == b'\x00\x01\x02\x00\xc0'
|
|
8478
|
+
assert quarantine == b''
|
|
8479
|
+
assert nrows == 1
|
|
8480
|
+
assert nquarantine == 0
|
|
8481
|
+
|
|
8482
|
+
@pytest.mark.parametrize("legacy_conversion_mode", [True, False])
|
|
8483
|
+
def test_convert_ipv6_to_row_binary(self, legacy_conversion_mode):
|
|
8484
|
+
schema = json.dumps(get_schema([('address', 'IPv6', '$.address', False)]))
|
|
8485
|
+
|
|
8486
|
+
with chquery.RowBinaryEncoder(schema, legacy_conversion_mode=legacy_conversion_mode) as encoder:
|
|
8487
|
+
result, quarantine, nrows, nquarantine = encoder.encode('{"address": "2001:db8::1"}')
|
|
8488
|
+
|
|
8489
|
+
assert result == b'\x00\x20\x01\x0d\xb8' + b'\x00' * 11 + b'\x01'
|
|
8490
|
+
assert quarantine == b''
|
|
8491
|
+
assert nrows == 1
|
|
8492
|
+
assert nquarantine == 0
|
|
8493
|
+
|
|
8494
|
+
@pytest.mark.parametrize("legacy_conversion_mode", [True, False])
|
|
8495
|
+
def test_convert_ipv4_formatted_address_to_ipv6_row_binary(self, legacy_conversion_mode):
|
|
8496
|
+
schema = json.dumps(get_schema([('address', 'IPv6', '$.address', False)]))
|
|
8497
|
+
|
|
8498
|
+
with chquery.RowBinaryEncoder(schema, legacy_conversion_mode=legacy_conversion_mode) as encoder:
|
|
8499
|
+
result, quarantine, nrows, nquarantine = encoder.encode('{"address": "1.1.1.1"}')
|
|
8500
|
+
|
|
8501
|
+
assert result == b'\x00' + b'\x00' * 10 + b'\xff\xff\x01\x01\x01\x01'
|
|
8502
|
+
assert quarantine == b''
|
|
8503
|
+
assert nrows == 1
|
|
8504
|
+
assert nquarantine == 0
|
|
8505
|
+
|
|
8506
|
+
@pytest.mark.parametrize("legacy_conversion_mode", [True, False])
|
|
8507
|
+
@pytest.mark.parametrize("address_type", ["IPv4", "IPv6"])
|
|
8508
|
+
def test_invalid_ip_address_is_quarantined(self, legacy_conversion_mode, address_type):
|
|
8509
|
+
schema = json.dumps(get_schema([('address', address_type, '$.address', False)]))
|
|
8510
|
+
|
|
8511
|
+
with chquery.RowBinaryEncoder(schema, legacy_conversion_mode=legacy_conversion_mode) as encoder:
|
|
8512
|
+
result, quarantine, nrows, nquarantine = encoder.encode('{"address": "invalid-ip"}')
|
|
8513
|
+
|
|
8514
|
+
assert result == b''
|
|
8515
|
+
assert quarantine != b''
|
|
8516
|
+
assert b"invalid-ip" in quarantine
|
|
8517
|
+
assert nrows == 0
|
|
8518
|
+
assert nquarantine == 1
|
|
8519
|
+
|
|
8520
|
+
@pytest.mark.parametrize("legacy_conversion_mode", [True, False])
|
|
8521
|
+
@pytest.mark.parametrize("address", ["1.1.1.1junk", "2001:db8::1junk"])
|
|
8522
|
+
def test_ipv6_with_trailing_junk_is_quarantined(self, legacy_conversion_mode, address):
|
|
8523
|
+
schema = json.dumps(get_schema([('address', 'IPv6', '$.address', False)]))
|
|
8524
|
+
|
|
8525
|
+
with chquery.RowBinaryEncoder(schema, legacy_conversion_mode=legacy_conversion_mode) as encoder:
|
|
8526
|
+
result, quarantine, nrows, nquarantine = encoder.encode(json.dumps({"address": address}))
|
|
8527
|
+
|
|
8528
|
+
assert result == b''
|
|
8529
|
+
assert quarantine != b''
|
|
8530
|
+
assert address.encode() in quarantine
|
|
8531
|
+
assert nrows == 0
|
|
8532
|
+
assert nquarantine == 1
|
|
8533
|
+
|
|
8470
8534
|
@pytest.mark.parametrize("conversion_mode, schema, data, expected_result, expected_quarantine, expected_nrows, expected_nquarantine", TEST_CASES)
|
|
8471
8535
|
def test_legacy_convert_to_row_binary(self, conversion_mode, schema, data, expected_result, expected_quarantine, expected_nrows, expected_nquarantine):
|
|
8472
8536
|
schema_rowbinary = get_schema(schema)
|
|
@@ -2033,6 +2033,7 @@ SELECT *
|
|
|
2033
2033
|
optimize_aggregation_in_order = 1,
|
|
2034
2034
|
use_skip_indexes = 1,
|
|
2035
2035
|
use_skip_indexes_if_final = 0,
|
|
2036
|
+
do_not_merge_across_partitions_select_final = 1,
|
|
2036
2037
|
optimize_move_to_prewhere = 1,
|
|
2037
2038
|
query_plan_optimize_lazy_materialization = 0,
|
|
2038
2039
|
min_bytes_to_use_direct_io = 0,
|
|
@@ -333,6 +333,48 @@ class TestValidateTTL(unittest.TestCase):
|
|
|
333
333
|
f"{name} should be a known function in TTL WHERE clauses",
|
|
334
334
|
)
|
|
335
335
|
|
|
336
|
+
# --- Hash functions in sorting / primary keys (KeyDescription::parse) ---
|
|
337
|
+
def test_valid_sorting_key_with_cityhash64(self):
|
|
338
|
+
self.assertIsNone(
|
|
339
|
+
chquery.validate_ttl(
|
|
340
|
+
ttl="timestamp + INTERVAL 365 DAY",
|
|
341
|
+
columns=[
|
|
342
|
+
{"name": "organizationId", "type": "String"},
|
|
343
|
+
{"name": "surfaceId", "type": "String"},
|
|
344
|
+
{"name": "timestamp", "type": "DateTime"},
|
|
345
|
+
{"name": "name", "type": "String"},
|
|
346
|
+
{"name": "traceId", "type": "String"},
|
|
347
|
+
{"name": "spanId", "type": "String"},
|
|
348
|
+
{"name": "eventIndex", "type": "UInt32"},
|
|
349
|
+
],
|
|
350
|
+
sorting_key="organizationId, surfaceId, toDate(timestamp), name, cityHash64(traceId), spanId, eventIndex",
|
|
351
|
+
)
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
# --- Arithmetic functions in TTL expressions ---
|
|
355
|
+
def test_valid_ttl_with_int_div(self):
|
|
356
|
+
# Reported failure: "Unknown function intDiv".
|
|
357
|
+
self.assertIsNone(
|
|
358
|
+
chquery.validate_ttl(
|
|
359
|
+
ttl="toDateTime(intDiv(ts_server, 1000)) + INTERVAL 13 MONTH",
|
|
360
|
+
columns=[{"name": "ts_server", "type": "Int64"}],
|
|
361
|
+
sorting_key="ts_server",
|
|
362
|
+
)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
def test_valid_ttl_with_greatest(self):
|
|
366
|
+
# Reported failure: "Unknown function greatest".
|
|
367
|
+
self.assertIsNone(
|
|
368
|
+
chquery.validate_ttl(
|
|
369
|
+
ttl="greatest(departure_date, toDateTime(creation_date)) + toIntervalDay(2)",
|
|
370
|
+
columns=[
|
|
371
|
+
{"name": "departure_date", "type": "DateTime"},
|
|
372
|
+
{"name": "creation_date", "type": "Date"},
|
|
373
|
+
],
|
|
374
|
+
sorting_key="departure_date",
|
|
375
|
+
)
|
|
376
|
+
)
|
|
377
|
+
|
|
336
378
|
# --- Input validation ---
|
|
337
379
|
def test_columns_must_be_list_of_dicts(self):
|
|
338
380
|
with self.assertRaises(TypeError):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/requires.txt
RENAMED
|
File without changes
|
{tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/src/tinybird_toolset.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_get_columns_from_create_query.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird_toolset-2.5.0 → tinybird_toolset-2.5.4}/tests/test_replace_tables_backward_compat.py
RENAMED
|
File without changes
|
|
File without changes
|