tinybird 2.0.1.dev0__tar.gz → 3.0.1__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-2.0.1.dev0 → tinybird-3.0.1}/PKG-INFO +9 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/ch_utils/engine.py +2 -77
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/config.py +0 -4
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/datafile/common.py +79 -27
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/feedback_manager.py +0 -25
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/sql.py +6 -5
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/sql_template.py +389 -8
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/sql_toolset.py +3 -6
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/__cli__.py +2 -2
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/utils.py +5 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/build.py +30 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/build_common.py +7 -1
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/common.py +7 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/create.py +13 -8
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/build_datasource.py +0 -6
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/local_common.py +10 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/project.py +21 -10
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/common.py +5 -2
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tornado_template.py +8 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird.egg-info/PKG-INFO +9 -3
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/setup.cfg +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/__cli__.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/check_pypi.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/client.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/context.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/datatypes.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/git_settings.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/prompts.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/service_datasources.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/syncasync.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/cli.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/client.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/config.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/__init__.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/agent.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/animations.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/banner.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/command_agent.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/compactor.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/explore_agent.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/file_agent.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/memory.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/mock_agent.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/models.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/prompts.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/testing_agent.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/__init__.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/analyze.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/append.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/build.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/datafile.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/deploy.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/deploy_check.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/diff_resource.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/execute_query.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/file.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/get_endpoint_stats.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/get_openapi_definition.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/mock.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/plan.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/request_endpoint.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/run_command.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/secret.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/agent/tools/test.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/branch.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/cli.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/config.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/connection_kafka.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/connection_s3.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/format_connection.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/deployment_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/dev_server.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/info.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/job.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/job_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/local.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/local_logs.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/login.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/mock.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/mock_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/open.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/shell.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/table.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/test.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/test_common.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/token.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-2.0.1.dev0 → tinybird-3.0.1}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tinybird
|
|
3
|
-
Version:
|
|
3
|
+
Version: 3.0.1
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
7
7
|
Author-email: support@tinybird.co
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10, <3.14
|
|
9
9
|
Description-Content-Type: text/x-rst
|
|
10
10
|
Requires-Dist: aiofiles==24.1.0
|
|
11
11
|
Requires-Dist: anthropic==0.55.0
|
|
@@ -57,9 +57,15 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
57
57
|
Changelog
|
|
58
58
|
----------
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
3.0.1
|
|
61
61
|
*******
|
|
62
62
|
|
|
63
|
+
- `Experimental` Added hidden `--with-connections` flag to `tb build` and `tb dev` commands for enabling connection datasources (S3, Kafka, GCS) in branches. This is an experimental feature and is not yet publicly documented.
|
|
64
|
+
|
|
65
|
+
3.0.0
|
|
66
|
+
*******
|
|
67
|
+
|
|
68
|
+
- `Removed` Python 3.9 support. The minimum supported Python version is now 3.10.
|
|
63
69
|
- `Removed` BigQuery and Snowflake connector support from Forward CLI build and deployment commands
|
|
64
70
|
|
|
65
71
|
1.1.14
|
|
@@ -14,7 +14,6 @@ from ..sql import (
|
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
DEFAULT_EMPTY_PARAMETERS = ["ttl", "partition_key", "sorting_key"]
|
|
17
|
-
DEFAULT_JOIN_EMPTY_PARAMETERS = ["join_strictness", "join_type", "key_columns"]
|
|
18
17
|
|
|
19
18
|
# Currently we only support the simplest TTLs
|
|
20
19
|
# f(X) + toIntervalZ(N)
|
|
@@ -62,25 +61,6 @@ class TableDetails:
|
|
|
62
61
|
>>> ed.to_datafile()
|
|
63
62
|
'ENGINE "MergeTree"\\nENGINE_PARTITION_KEY "toYear(timestamp)"\\nENGINE_SORTING_KEY "timestamp, cityHash64(location)"\\nENGINE_SAMPLING_KEY "cityHash64(location)"\\nENGINE_SETTINGS "index_granularity = 32, index_granularity_bytes = 2048"\\nENGINE_TTL "toDate(timestamp) + INTERVAL 1 DAY"'
|
|
64
63
|
|
|
65
|
-
>>> ed = TableDetails({"engine_full": "Join(ANY, LEFT, id)", "engine": "Join", "partition_key": "", "sorting_key": "", "primary_key": "", "sampling_key": ""})
|
|
66
|
-
>>> ed.engine_full
|
|
67
|
-
'Join(ANY, LEFT, id)'
|
|
68
|
-
>>> ed.engine
|
|
69
|
-
'Join'
|
|
70
|
-
>>> ed.to_json()
|
|
71
|
-
{'engine_full': 'Join(ANY, LEFT, id)', 'engine': 'Join', 'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'id'}
|
|
72
|
-
>>> ed.to_datafile()
|
|
73
|
-
'ENGINE "Join"\\nENGINE_JOIN_STRICTNESS "ANY"\\nENGINE_JOIN_TYPE "LEFT"\\nENGINE_KEY_COLUMNS "id"'
|
|
74
|
-
|
|
75
|
-
>>> ed = TableDetails({"database": "d_01", "name": "t_01", "engine": "Join", "join_strictness": "ANY", "join_type": "LEFT", "key_columns": "id"})
|
|
76
|
-
>>> ed.engine_full == None
|
|
77
|
-
True
|
|
78
|
-
>>> ed.engine
|
|
79
|
-
'Join'
|
|
80
|
-
>>> ed.to_json()
|
|
81
|
-
{'engine_full': None, 'engine': 'Join', 'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'id'}
|
|
82
|
-
>>> ed.to_datafile()
|
|
83
|
-
'ENGINE "Join"\\nENGINE_JOIN_STRICTNESS "ANY"\\nENGINE_JOIN_TYPE "LEFT"\\nENGINE_KEY_COLUMNS "id"'
|
|
84
64
|
>>> ed = TableDetails({ "engine_full": "MergeTree() PARTITION BY toYear(timestamp) ORDER BY (timestamp, cityHash64(location)) SAMPLE BY cityHash64(location) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1, merge_with_ttl_timeout = 1800 TTL toDate(timestamp) + INTERVAL 1 DAY"})
|
|
85
65
|
>>> ed.engine_full
|
|
86
66
|
'MergeTree() PARTITION BY toYear(timestamp) ORDER BY (timestamp, cityHash64(location)) SAMPLE BY cityHash64(location) SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1, merge_with_ttl_timeout = 1800 TTL toDate(timestamp) + INTERVAL 1 DAY'
|
|
@@ -222,21 +202,6 @@ class TableDetails:
|
|
|
222
202
|
_sign = self.details.get("sign", None)
|
|
223
203
|
return _sign
|
|
224
204
|
|
|
225
|
-
@property
|
|
226
|
-
def join_strictness(self):
|
|
227
|
-
_join_strictness = self.details.get("join_strictness", None)
|
|
228
|
-
return _join_strictness
|
|
229
|
-
|
|
230
|
-
@property
|
|
231
|
-
def join_type(self):
|
|
232
|
-
_join_type = self.details.get("join_type", None)
|
|
233
|
-
return _join_type
|
|
234
|
-
|
|
235
|
-
@property
|
|
236
|
-
def key_columns(self):
|
|
237
|
-
_key_columns = self.details.get("key_columns", None)
|
|
238
|
-
return _key_columns
|
|
239
|
-
|
|
240
205
|
@property
|
|
241
206
|
def statistics(self) -> Dict[str, Any]:
|
|
242
207
|
return {
|
|
@@ -268,12 +233,6 @@ class TableDetails:
|
|
|
268
233
|
d["sampling_key"] = self.sampling_key
|
|
269
234
|
if self.settings:
|
|
270
235
|
d["settings"] = self.settings
|
|
271
|
-
if self.join_strictness:
|
|
272
|
-
d["join_strictness"] = self.join_strictness
|
|
273
|
-
if self.join_type:
|
|
274
|
-
d["join_type"] = self.join_type
|
|
275
|
-
if self.key_columns:
|
|
276
|
-
d["key_columns"] = self.key_columns
|
|
277
236
|
if self.ver:
|
|
278
237
|
d["ver"] = self.ver
|
|
279
238
|
if self.is_deleted:
|
|
@@ -292,10 +251,7 @@ class TableDetails:
|
|
|
292
251
|
d = {**d, **engine_params}
|
|
293
252
|
|
|
294
253
|
if include_empty_details:
|
|
295
|
-
|
|
296
|
-
d = set_empty_details(d, DEFAULT_JOIN_EMPTY_PARAMETERS)
|
|
297
|
-
else:
|
|
298
|
-
d = set_empty_details(d, DEFAULT_EMPTY_PARAMETERS)
|
|
254
|
+
d = set_empty_details(d, DEFAULT_EMPTY_PARAMETERS)
|
|
299
255
|
|
|
300
256
|
if exclude:
|
|
301
257
|
for attr in exclude:
|
|
@@ -480,20 +436,6 @@ ENABLED_ENGINES = [
|
|
|
480
436
|
],
|
|
481
437
|
MERGETREE_OPTIONS,
|
|
482
438
|
),
|
|
483
|
-
# Join(join_strictness, join_type, k1[, k2, ...])
|
|
484
|
-
engine_config(
|
|
485
|
-
"Join",
|
|
486
|
-
[
|
|
487
|
-
# https://github.com/ClickHouse/ClickHouse/blob/fa8e4e4735b932f08b6beffcb2d069b72de34401/src/Storages/StorageJoin.cpp
|
|
488
|
-
EngineParam(
|
|
489
|
-
name="join_strictness", required=True, is_valid=case_insensitive_check(["ANY", "ALL", "SEMI", "ANTI"])
|
|
490
|
-
),
|
|
491
|
-
EngineParam(
|
|
492
|
-
name="join_type", required=True, is_valid=case_insensitive_check(["LEFT", "INNER", "RIGHT", "FULL"])
|
|
493
|
-
),
|
|
494
|
-
EngineParam(name="key_columns", required=True, is_valid=columns_are_valid),
|
|
495
|
-
],
|
|
496
|
-
),
|
|
497
439
|
# Null()
|
|
498
440
|
engine_config("Null"),
|
|
499
441
|
]
|
|
@@ -599,7 +541,7 @@ def engine_full_from_dict(
|
|
|
599
541
|
>>> engine_full_from_dict('wadus', {}, schema=schema)
|
|
600
542
|
Traceback (most recent call last):
|
|
601
543
|
...
|
|
602
|
-
ValueError: Engine wadus is not supported, supported engines include: MergeTree, ReplacingMergeTree, SummingMergeTree, AggregatingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree,
|
|
544
|
+
ValueError: Engine wadus is not supported, supported engines include: MergeTree, ReplacingMergeTree, SummingMergeTree, AggregatingMergeTree, CollapsingMergeTree, VersionedCollapsingMergeTree, Null
|
|
603
545
|
>>> schema = ''
|
|
604
546
|
>>> engine_full_from_dict('null', {}, schema=schema)
|
|
605
547
|
'Null()'
|
|
@@ -607,19 +549,6 @@ def engine_full_from_dict(
|
|
|
607
549
|
>>> engine_full_from_dict('null', {}, columns=[])
|
|
608
550
|
'Null()'
|
|
609
551
|
|
|
610
|
-
>>> schema = 'cid Int32'
|
|
611
|
-
>>> engine_full_from_dict('Join', {'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'cid'}, schema=schema)
|
|
612
|
-
'Join(ANY, LEFT, cid)'
|
|
613
|
-
>>> engine_full_from_dict('Join', {'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'cid'}, columns=[{'name': 'cid', 'type': 'Int32', 'codec': None, 'default_value': None, 'nullable': False, 'normalized_name': 'cid'}])
|
|
614
|
-
'Join(ANY, LEFT, cid)'
|
|
615
|
-
>>> schema = 'cid1 Int32, cid2 Int8'
|
|
616
|
-
>>> engine_full_from_dict('Join', {'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'cid1, cid2'}, schema=schema)
|
|
617
|
-
'Join(ANY, LEFT, cid1, cid2)'
|
|
618
|
-
>>> engine_full_from_dict('Join', {'join_strictness': 'ANY', 'join_type': 'OUTER', 'key_columns': 'cid'}, schema=schema)
|
|
619
|
-
Traceback (most recent call last):
|
|
620
|
-
...
|
|
621
|
-
ValueError: Invalid value 'OUTER' for parameter 'engine_join_type', reason: valid values are LEFT, INNER, RIGHT, FULL
|
|
622
|
-
|
|
623
552
|
>>> schema = ''
|
|
624
553
|
>>> engine_full_from_dict('MergeTree', {}, schema=schema)
|
|
625
554
|
'MergeTree() ORDER BY (tuple())'
|
|
@@ -715,10 +644,6 @@ def engine_params_from_engine_full(engine_full: str) -> Dict[str, Any]:
|
|
|
715
644
|
"""
|
|
716
645
|
>>> engine_params_from_engine_full("Null()")
|
|
717
646
|
{}
|
|
718
|
-
>>> engine_params_from_engine_full("Join(ANY, LEFT, id)")
|
|
719
|
-
{'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'id'}
|
|
720
|
-
>>> engine_params_from_engine_full("Join(ANY, LEFT, k1, k2)")
|
|
721
|
-
{'join_strictness': 'ANY', 'join_type': 'LEFT', 'key_columns': 'k1, k2'}
|
|
722
647
|
>>> engine_params_from_engine_full("AggregatingMergeTree('/clickhouse/tables/{layer}-{shard}/d_f837aa.sales_by_country_rt__v0_staging_t_00c3091e7530472caebda05e97288a1d', '{replica}') PARTITION BY toYYYYMM(date) ORDER BY (purchase_location, cod_device, date) SETTINGS index_granularity = 8192")
|
|
723
648
|
{}
|
|
724
649
|
>>> engine_params_from_engine_full("ReplicatedSummingMergeTree('/clickhouse/tables/{layer}-{shard}/d_abcf3e.t_69f9da31f4524995b8911e1b24c80ab4', '{replica}') PARTITION BY toYYYYMM(date) ORDER BY (date, purchase_location, sku_rank_lc) SETTINGS index_granularity = 8192")
|
|
@@ -33,6 +33,13 @@ from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
|
33
33
|
# I'll try not to make logic changes, just error reporting changes
|
|
34
34
|
# from tinybird.sql import parse_indexes_structure, parse_table_structure, schema_to_sql_columns
|
|
35
35
|
|
|
36
|
+
# Pre-compiled regex patterns
|
|
37
|
+
_PATTERN_INDEX_ENTRY = re.compile(
|
|
38
|
+
r"(\w+)\s+([\w\s*\[\]\*\(\),\'\"-><.]+)\s+TYPE\s+(\w+)(?:\(([\w\s*.,]+)\))?(?:\s+GRANULARITY\s+(\d+))?"
|
|
39
|
+
)
|
|
40
|
+
_PATTERN_SIMPLE_AGG_FUNC = re.compile(r"SimpleAggregateFunction\((\w+),\s*(?!(?:Nullable))([\w,.()]+)\)")
|
|
41
|
+
_PATTERN_VERSION_NUMBER = re.compile(r"[0-9]+$")
|
|
42
|
+
|
|
36
43
|
|
|
37
44
|
class DatafileValidationError(Exception): ...
|
|
38
45
|
|
|
@@ -271,6 +278,74 @@ VALID_BLOB_STORAGE_CRON_VALUES = {
|
|
|
271
278
|
}
|
|
272
279
|
|
|
273
280
|
|
|
281
|
+
def extract_column_names_from_sorting_key_part(part: str) -> List[str]:
|
|
282
|
+
"""
|
|
283
|
+
Extract actual column names from a sorting key part (which might be an expression).
|
|
284
|
+
|
|
285
|
+
Examples:
|
|
286
|
+
- "shop" -> ["shop"]
|
|
287
|
+
- "`column_name`" -> ["column_name"]
|
|
288
|
+
- "ifNull(ad_id, '')" -> ["ad_id"]
|
|
289
|
+
- "toDate(timestamp)" -> ["timestamp"]
|
|
290
|
+
- "concat(first_name, last_name)" -> ["first_name", "last_name"]
|
|
291
|
+
"""
|
|
292
|
+
columns = []
|
|
293
|
+
|
|
294
|
+
if "(" in part and part.endswith(")"):
|
|
295
|
+
# Function expression - extract column names from inside parentheses
|
|
296
|
+
func_start = part.find("(")
|
|
297
|
+
inner_content = part[func_start + 1 : -1].strip()
|
|
298
|
+
for inner_part in inner_content.split(","):
|
|
299
|
+
inner_part = inner_part.strip().strip("`")
|
|
300
|
+
if inner_part and inner_part.isidentifier():
|
|
301
|
+
columns.append(inner_part)
|
|
302
|
+
elif part:
|
|
303
|
+
# Simple column name
|
|
304
|
+
column_name = part.strip("`")
|
|
305
|
+
if column_name:
|
|
306
|
+
columns.append(column_name)
|
|
307
|
+
|
|
308
|
+
return columns
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def parse_sorting_key_column_names(sorting_key: str) -> List[str]:
|
|
312
|
+
"""
|
|
313
|
+
Extract all column names from a sorting key expression.
|
|
314
|
+
|
|
315
|
+
Examples:
|
|
316
|
+
- "shop, event_date, channel" -> ["shop", "event_date", "channel"]
|
|
317
|
+
- "shop, event_date, ifNull(ad_id, ''), event_id" -> ["shop", "event_date", "ad_id", "event_id"]
|
|
318
|
+
- "tuple(shop, toDate(timestamp))" -> ["shop", "timestamp"]
|
|
319
|
+
"""
|
|
320
|
+
# Remove tuple() wrapper if present
|
|
321
|
+
column_str = sorting_key
|
|
322
|
+
if column_str.startswith("tuple(") and column_str.endswith(")"):
|
|
323
|
+
column_str = column_str[6:-1]
|
|
324
|
+
|
|
325
|
+
sorting_key_columns = []
|
|
326
|
+
|
|
327
|
+
# Use regex to find all sorting key parts, respecting parentheses and quotes
|
|
328
|
+
# Pattern matches: function calls with args, or simple identifiers
|
|
329
|
+
# This handles cases like: ifNull(col, ''), toDate(timestamp), simple_col
|
|
330
|
+
pattern = r"""
|
|
331
|
+
(?: # Non-capturing group for the whole part
|
|
332
|
+
\w+\s*\([^)]*\) # Function call: word + ( + anything except ) + )
|
|
333
|
+
| # OR
|
|
334
|
+
`[^`]+` # Backtick-quoted identifier
|
|
335
|
+
| # OR
|
|
336
|
+
\w+ # Simple word/identifier
|
|
337
|
+
)
|
|
338
|
+
"""
|
|
339
|
+
|
|
340
|
+
for match in re.finditer(pattern, column_str, re.VERBOSE):
|
|
341
|
+
part = match.group(0).strip()
|
|
342
|
+
# Extract column names from the part (handles both simple columns and function expressions)
|
|
343
|
+
extracted_columns = extract_column_names_from_sorting_key_part(part)
|
|
344
|
+
sorting_key_columns.extend(extracted_columns)
|
|
345
|
+
|
|
346
|
+
return sorting_key_columns
|
|
347
|
+
|
|
348
|
+
|
|
274
349
|
class Datafile:
|
|
275
350
|
def __init__(self) -> None:
|
|
276
351
|
self.maintainer: Optional[str] = None
|
|
@@ -559,7 +634,7 @@ class Datafile:
|
|
|
559
634
|
)
|
|
560
635
|
|
|
561
636
|
# Extract column names from the part
|
|
562
|
-
extracted_columns =
|
|
637
|
+
extracted_columns = extract_column_names_from_sorting_key_part(part)
|
|
563
638
|
sorting_key_columns.extend(extracted_columns)
|
|
564
639
|
|
|
565
640
|
return sorting_key_columns
|
|
@@ -595,26 +670,6 @@ class Datafile:
|
|
|
595
670
|
|
|
596
671
|
return func_name in aggregate_function_names
|
|
597
672
|
|
|
598
|
-
def _extract_column_names_from_part(self, part: str) -> List[str]:
|
|
599
|
-
"""Extract column names from a sorting key part."""
|
|
600
|
-
columns = []
|
|
601
|
-
|
|
602
|
-
if "(" in part and part.endswith(")"):
|
|
603
|
-
# Function expression - extract column names from inside parentheses
|
|
604
|
-
func_start = part.find("(")
|
|
605
|
-
inner_content = part[func_start + 1 : -1].strip()
|
|
606
|
-
for inner_part in inner_content.split(","):
|
|
607
|
-
inner_part = inner_part.strip().strip("`")
|
|
608
|
-
if inner_part and inner_part.isidentifier():
|
|
609
|
-
columns.append(inner_part)
|
|
610
|
-
elif part:
|
|
611
|
-
# Simple column name
|
|
612
|
-
column_name = part.strip("`")
|
|
613
|
-
if column_name:
|
|
614
|
-
columns.append(column_name)
|
|
615
|
-
|
|
616
|
-
return columns
|
|
617
|
-
|
|
618
673
|
def _validate_columns_against_schema(
|
|
619
674
|
self, sorting_key_columns: List[str], schema_columns: Dict[str, Dict[str, Any]]
|
|
620
675
|
) -> None:
|
|
@@ -783,10 +838,7 @@ def parse_indexes_structure(indexes: Optional[List[str]]) -> List[TableIndex]:
|
|
|
783
838
|
pos=leading_whitespaces + 1,
|
|
784
839
|
)
|
|
785
840
|
|
|
786
|
-
match =
|
|
787
|
-
r"(\w+)\s+([\w\s*\[\]\*\(\),\'\"-><.]+)\s+TYPE\s+(\w+)(?:\(([\w\s*.,]+)\))?(?:\s+GRANULARITY\s+(\d+))?",
|
|
788
|
-
index,
|
|
789
|
-
)
|
|
841
|
+
match = _PATTERN_INDEX_ENTRY.match(index)
|
|
790
842
|
if match:
|
|
791
843
|
index_name, a, index_type, value, granularity = match.groups()
|
|
792
844
|
index_expr = f"{index_type}({value})" if value else index_type
|
|
@@ -1323,7 +1375,7 @@ def try_to_fix_nullable_in_simple_aggregating_function(t: str) -> Optional[str]:
|
|
|
1323
1375
|
# as it is done with other aggregate functions.
|
|
1324
1376
|
# If not, the aggregation could return incorrect results.
|
|
1325
1377
|
result = None
|
|
1326
|
-
if match :=
|
|
1378
|
+
if match := _PATTERN_SIMPLE_AGG_FUNC.search(t):
|
|
1327
1379
|
fn = match.group(1)
|
|
1328
1380
|
inner_type = match.group(2)
|
|
1329
1381
|
result = f"SimpleAggregateFunction({fn}, Nullable({inner_type}))"
|
|
@@ -2468,7 +2520,7 @@ def get_name_version(ds: str) -> Dict[str, Any]:
|
|
|
2468
2520
|
return {"name": tk[0], "version": None}
|
|
2469
2521
|
elif len(tk) == 2:
|
|
2470
2522
|
if len(tk[1]):
|
|
2471
|
-
if tk[1][0] == "v" and
|
|
2523
|
+
if tk[1][0] == "v" and _PATTERN_VERSION_NUMBER.match(tk[1][1:]):
|
|
2472
2524
|
return {"name": tk[0], "version": int(tk[1][1:])}
|
|
2473
2525
|
else:
|
|
2474
2526
|
return {"name": tk[0] + "__" + tk[1], "version": None}
|
|
@@ -305,12 +305,6 @@ class FeedbackManager:
|
|
|
305
305
|
error_unknown_kafka_connection = error_message(
|
|
306
306
|
"Unknown Kafka connection in Data Source '{datasource}'. Hint: you can create it with the 'tb connection create kafka' command.\n** See https://www.tinybird.co/docs/ingest/kafka.html?highlight=kafka#using-include-to-store-connection-settings to learn more."
|
|
307
307
|
)
|
|
308
|
-
error_unknown_bq_connection = error_message(
|
|
309
|
-
"Unknown BigQuery connection in Data Source '{datasource}'. Hint: you can create it with the 'tb connection create bigquery' command."
|
|
310
|
-
)
|
|
311
|
-
error_unknown_snowflake_connection = error_message(
|
|
312
|
-
"Unknown Snowflake connection in Data Source '{datasource}'. Hint: you can create it with the 'tb connection create snowflake' command."
|
|
313
|
-
)
|
|
314
308
|
error_unknown_connection_service = error_message("Unknown connection service '{service}'")
|
|
315
309
|
error_missing_connection_name = error_message("Missing IMPORT_CONNECTION_NAME in '{datasource}'.")
|
|
316
310
|
error_missing_external_datasource = error_message(
|
|
@@ -417,9 +411,6 @@ class FeedbackManager:
|
|
|
417
411
|
error_updating_tag = error_message("Error updating tag: {error}")
|
|
418
412
|
error_tag_generic = error_message("There was an issue updating tags. {error}")
|
|
419
413
|
error_tag_not_found = error_message("Tag {tag_name} not found.")
|
|
420
|
-
error_snowflake_connector_not_enabled = error_message(
|
|
421
|
-
"🚨🚨🚨 [DEPRECATED] Snowflake connector is deprecated. Can't create the connector. **"
|
|
422
|
-
)
|
|
423
414
|
|
|
424
415
|
info_incl_relative_path = info_message("** Relative path {path} does not exist, skipping.")
|
|
425
416
|
info_ignoring_incl_file = info_message(
|
|
@@ -468,13 +459,6 @@ class FeedbackManager:
|
|
|
468
459
|
prompt_ws_name = prompt_message("❓ Workspace name:")
|
|
469
460
|
prompt_ws_template = prompt_message("❓ Starter template:")
|
|
470
461
|
|
|
471
|
-
prompt_bigquery_account = prompt_message(
|
|
472
|
-
"""** Log into your Google Cloud Platform Console as a project editor and go to https://console.cloud.google.com/iam-admin/iam
|
|
473
|
-
** Grant access to this principal: {service_account}
|
|
474
|
-
** Assign it the role "BigQuery Data Viewer"
|
|
475
|
-
Ready? """
|
|
476
|
-
)
|
|
477
|
-
|
|
478
462
|
prompt_s3_iamrole_connection_login_aws = prompt_message("""[1] Log into your AWS Console\n\n""")
|
|
479
463
|
prompt_s3_iamrole_connection_policy = prompt_message(
|
|
480
464
|
"""\n[2] Go to IAM > Policies. Create a new policy with the following permissions. Please, replace {replacements}:\n\n{access_policy}\n\n(The policy has been copied to your clipboard)\n\n"""
|
|
@@ -509,12 +493,6 @@ Ready? """
|
|
|
509
493
|
error_bump_release = error_message(
|
|
510
494
|
"Error: Bump the --semver flag, example 'tb --semver 0.0.2 {command}'. If you are in CI, bump the VERSION envvar in .tinyenv\n"
|
|
511
495
|
)
|
|
512
|
-
error_bigquery_improper_permissions = error_message(
|
|
513
|
-
"Error: no access detected. It might take a minute to detect the new permissions.\n"
|
|
514
|
-
)
|
|
515
|
-
error_snowflake_improper_permissions = error_message(
|
|
516
|
-
"Snowflake connection is not valid. Please check your credentials and try again.\n"
|
|
517
|
-
)
|
|
518
496
|
error_connection_improper_permissions = error_message(
|
|
519
497
|
"Connection is not valid. Please check your credentials and try again.\n"
|
|
520
498
|
)
|
|
@@ -646,9 +624,6 @@ Ready? """
|
|
|
646
624
|
warning_tag_remove = prompt_message(
|
|
647
625
|
"Tag {tag_name} is used by {resources_len} resources. Do you want to remove it?"
|
|
648
626
|
)
|
|
649
|
-
warning_bigquery_connector_deprecated = warning_message(
|
|
650
|
-
"🚨🚨🚨 [DEPRECATED] BigQuery connector is deprecated. Use ingestion from GCS instead. https://www.tinybird.co/docs/get-data-in/guides/ingest-from-bigquery-using-google-cloud-storage **"
|
|
651
|
-
)
|
|
652
627
|
warning_s3_access_key_secret_deprecated = warning_message(
|
|
653
628
|
"🚨🚨🚨 [DEPRECATED] S3 (Access Key + Secret) connector is deprecated. Use S3 IAM role instead. https://www.tinybird.co/docs/get-data-in/connectors/s3 **"
|
|
654
629
|
)
|
|
@@ -39,6 +39,7 @@ _RE_INDEX_ENTRY = re.compile(
|
|
|
39
39
|
r"(\w+)\s+([\w\s*\[\]\*\(\),\'\"-><.]+)\s+TYPE\s+(\w+)(?:\(([\w\s*.,]+)\))?(?:\s+GRANULARITY\s+(\d+))?"
|
|
40
40
|
)
|
|
41
41
|
_RE_REPLICATED_MT = re.compile(r"Replicated(.*)MergeTree\(([^\)]*)\)(.*)")
|
|
42
|
+
_RE_REPLICATED_ENGINE_SPLIT = re.compile(r"(Replicated.*MergeTree\(')([^']*)('.*)")
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
@dataclass
|
|
@@ -836,7 +837,7 @@ def engine_can_be_replicated(engine: Optional[str]) -> bool:
|
|
|
836
837
|
"""
|
|
837
838
|
>>> engine_can_be_replicated('MergeTree() order by tuple()')
|
|
838
839
|
True
|
|
839
|
-
>>> engine_can_be_replicated('
|
|
840
|
+
>>> engine_can_be_replicated('Null')
|
|
840
841
|
False
|
|
841
842
|
>>> engine_can_be_replicated('ReplicatingMergeTree() order by tuple()')
|
|
842
843
|
True
|
|
@@ -855,7 +856,7 @@ def engine_supports_delete(engine: Optional[str]) -> bool:
|
|
|
855
856
|
"""
|
|
856
857
|
>>> engine_supports_delete('MergeTree() order by tuple()')
|
|
857
858
|
True
|
|
858
|
-
>>> engine_supports_delete('
|
|
859
|
+
>>> engine_supports_delete('Null')
|
|
859
860
|
False
|
|
860
861
|
>>> engine_supports_delete('ReplicatingMergeTree() order by tuple()')
|
|
861
862
|
True
|
|
@@ -873,8 +874,8 @@ def engine_replicated_to_local(engine: str) -> str:
|
|
|
873
874
|
'MergeTree() order by (test)'
|
|
874
875
|
>>> engine_replicated_to_local("ReplicatedReplacingMergeTree('/clickhouse/tables/{layer}-{shard}/test.foo', '{replica}', timestamp) order by (test)")
|
|
875
876
|
'ReplacingMergeTree(timestamp) order by (test)'
|
|
876
|
-
>>> engine_replicated_to_local("
|
|
877
|
-
'
|
|
877
|
+
>>> engine_replicated_to_local("Null")
|
|
878
|
+
'Null'
|
|
878
879
|
>>> engine_replicated_to_local("ReplicatedVersionedCollapsingMergeTree('/clickhouse/tables/{layer}-{shard}/test.foo', '{replica}', sign,version) ORDER BY pk TTL toDate(local_timeplaced) + toIntervalDay(3) SETTINGS index_granularity = 8192")
|
|
879
880
|
'VersionedCollapsingMergeTree(sign, version) ORDER BY pk TTL toDate(local_timeplaced) + toIntervalDay(3) SETTINGS index_granularity = 8192'
|
|
880
881
|
"""
|
|
@@ -911,7 +912,7 @@ def engine_patch_replicated_engine(engine: str, engine_full: Optional[str], new_
|
|
|
911
912
|
if not engine_full:
|
|
912
913
|
return None
|
|
913
914
|
if engine.lower().startswith("Replicated".lower()):
|
|
914
|
-
parts =
|
|
915
|
+
parts = _RE_REPLICATED_ENGINE_SPLIT.split(engine_full)
|
|
915
916
|
paths = parts[2].split("/")
|
|
916
917
|
paths[-1] = new_table_name
|
|
917
918
|
zoo_path = "/".join(paths)
|