Infer wildcard partition strategy from a {_partition_id} path on CREATE - #111279
Conversation
After #107437, a CREATE statement with a `{_partition_id}` placeholder in the path and no explicit `partition_strategy` was rejected with `BAD_ARGUMENTS` whenever the effective `file_like_engine_default_partition_strategy` default was `hive` (the default since 26.6). This broke pre-26.6 DDL and DDL generators that rely on the implicit wildcard strategy. A `{_partition_id}` placeholder is valid only under the `wildcard` strategy, so when no explicit strategy is given the path alone determines the only strategy that can work. `initPartitionStrategy` now infers `wildcard` from the path shape on CREATE, the same way it already does on ATTACH / server startup / RESTORE. The default setting only applies to paths without the placeholder, and an explicit `partition_strategy = 'hive'` still rejects such paths. Related: #106465 Related: #86746
|
Workflow [PR], commit [82d543e] Summary: ❌
AI ReviewSummaryThis PR restores the implicit Findings
Final VerdictStatus: |
The flaky check runs the test several times concurrently against the same S3 bucket, which exposed three test bugs: S3 keys were shared between runs, the main read glob `test_04614_implicit_wildcard_*` also matched the table-function output `..._fn_55`, and the untyped literal `SELECT 55 AS a` wrote a `UInt8` parquet column - when schema inference picked that file's schema, every value was cast to `UInt8` (`333` -> `77`, `4444` -> `92`). Prefix all keys with `currentDatabase()`, use disjoint `tbl_`/`fn_` prefixes, and type the literal as `UInt64`. CI: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=111279&sha=e25642ae15185036b93ee94dc6c2c3c4c0fe52d9&name_0=PR&name_1=Stateless%20tests%20%28amd_asan_ubsan%2C%20flaky%20check%29 PR: #111279
The `partition_strategy` defaulting description in the in-source docs
and the S3/AzureBlobStorage doc pages said the default comes solely
from `file_like_engine_default_partition_strategy`. Since the implicit
strategy is now derived from the path shape first, state that a
`{_partition_id}` placeholder implies `wildcard` and the setting only
applies to paths without the placeholder. Also clarify the setting
description itself.
PR: #111279
|
Good catch — the defaulting contract description was indeed stale after this change. Updated in b242110:
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
Master reworded the partition_strategy defaulting docs (setting-only
contract, "paths containing {_partition_id} must explicitly set
partition_strategy='wildcard'"), which conflicts with the path-shape
inference this PR introduces. Kept this branch's wording and applied
the path-shape rule to the reworded gcs variants that merged cleanly.
The "Partitioned Write" sections of the gcs and azureBlobStorage table
function docs still said that paths containing `{_partition_id}`
require an explicit `wildcard` strategy under the 26.6 `hive` default,
contradicting the argument tables updated earlier in this PR. Also
refresh the generated `session-settings.mdx` entry for
`file_like_engine_default_partition_strategy` to match the new
description in `Settings.cpp`.
PR: #111279
|
Both follow-ups addressed in df01945:
A repo-wide sweep for the stale wording ("require an explicit", "is the default partition strategy", "must explicitly set |
Master replaced the static autogenerated session-settings page with the SessionSettingsExplorer component, deleting the text this branch had edited. Took master's version: the explorer renders setting descriptions from source, so the updated `file_like_engine_default_partition_strategy` description in `Settings.cpp` flows through without a checked-in page edit.
| | `structure` | Structure of the table. Format `'column1_name column1_type, column2_name column2_type, ...'`. | | ||
| | `compression_method` | Parameter is optional. Supported values: `none`, `gzip` or `gz`, `brotli` or `br`, `xz` or `LZMA`, `zstd` or `zst`. By default, it will autodetect compression method by file extension. | | ||
| | `partition_strategy` | Optional. Supported values: `wildcard` or `hive`. `wildcard` requires `{_partition_id}` in the path. It is the default only when `compatibility` is older than `26.6`; otherwise, including when current defaults apply, the default is `hive`. | | ||
| | `partition_strategy` | Optional. Supported values: `wildcard` or `hive`. `wildcard` requires `{_partition_id}` in the path. It is the default when the path contains `{_partition_id}` (the only strategy compatible with such a path), or when `compatibility` is older than `26.6`; otherwise, including when current defaults apply, the default is `hive`. | |
There was a problem hiding this comment.
gcs still has one stale public-docs surface in the current tree: docs/en/sql-reference/table-functions/gcs.md was not updated alongside this source/Mintlify change. Its argument table at line 40 still omits that a {_partition_id} path implicitly selects wildcard, and its ## Partitioned Write section at line 191 still lacks the new note that the explicit partition_strategy='wildcard' is optional. Since docs/en is the current Docusaurus source, the published gcs docs stay inconsistent unless that page is updated too.
The "Docs check (Mintlify)" job forbids direct edits inside AUTOGENERATED regions of docs/reference. The partition strategy defaulting fixes remain in the generator sources: the in-source docs in registerStorageObjectStorage.cpp / TableFunctionObjectStorage.cpp, the docs/en pages, and the Settings.cpp setting description. The generated mirrors will be refreshed by the docs pipeline. CI: https://s3.amazonaws.com/clickhouse-test-reports/json.html?PR=111279&sha=866a3ecbe1b58da3f25485dab0f99931956a5a23&name_0=PR&name_1=Docs%20check%20%28Mintlify%29 PR: #111279
LLVM Coverage Report
Changed lines: Changed C/C++ lines covered: 67/67 (100.00%) · Uncovered code |
Backport #111279 to 26.7: Infer wildcard partition strategy from a `{_partition_id}` path on CREATE
Cherry pick #111279 to 26.6: Infer wildcard partition strategy from a `{_partition_id}` path on CREATE
…_partition_id}` path on CREATE
Backport #111279 to 26.6: Infer wildcard partition strategy from a `{_partition_id}` path on CREATE
Related: #107437
Related: #86746
Related: #106465
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes into CHANGELOG.md):
A
{_partition_id}placeholder in the path of a file-like engine (S3,AzureBlobStorage,URL, etc.) with no explicitpartition_strategyimplies thewildcardstrategy again, regardless offile_like_engine_default_partition_strategy. This restores backward compatibility for pre-26.6 DDL that started failing withBAD_ARGUMENTS("Partition strategy hive can not be used with a '_partition_id' wildcard in the path") after #107437.Motivation
#86746 made
hivethe default partition strategy for file-like engines fromcompatibility >= 26.6, but an unconditional compatibility shim kept{_partition_id}paths working. #107437 removed that shim to fix the validation inconsistency from #106465 — and thereby broke every pre-26.6CREATEstatement (and DDL generator) that uses a{_partition_id}path with no explicitpartition_strategy: under thehivedefault they now fail withBAD_ARGUMENTS.The key observation: the two strategies are mutually exclusive on path shape —
wildcardrequires{_partition_id}in the path,hiveforbids it. So when the user writes{_partition_id}and does not specify a strategy, the path alone determines the only strategy that can possibly work. Rejecting it forces the user to typepartition_strategy = 'wildcard'— information the path already carries unambiguously.This PR makes
initPartitionStrategyinferwildcardfrom the path shape onCREATE, exactly the way it already does onATTACH/ server startup /RESTOREsince #107437. Thefile_like_engine_default_partition_strategydefault now only applies to paths without the placeholder. The actual validation fix of #107437 is fully preserved: an explicitpartition_strategy = 'hive'with a{_partition_id}path still raisesBAD_ARGUMENTS, andATTACHpath-shape inference is unchanged.Full behavior matrix
CREATE(and table functions), withPARTITION BY:{_partition_id}partition_strategycompatibility)wildcard(compat < 26.6)hive(compat ≥ 26.6)BAD_ARGUMENTS(the break)wildcardhiveBAD_ARGUMENTSBAD_ARGUMENTSBAD_ARGUMENTSBAD_ARGUMENTSwildcard(compat < 26.6)BAD_ARGUMENTS(wildcard requires the placeholder)BAD_ARGUMENTSBAD_ARGUMENTSBAD_ARGUMENTShive(compat ≥ 26.6)wildcardBAD_ARGUMENTSBAD_ARGUMENTSBAD_ARGUMENTSBAD_ARGUMENTShiveATTACH/ server startup /RESTORE/ replicated-DDL replay, implicit strategy (strategy is derived from path shape, never from the mutable default — introduced by #107437, unchanged here):{_partition_id}The only behavior change of this PR is the single bold cell: implicit strategy +
{_partition_id}path onCREATEunder thehivedefault works again, as it did in every release before 26.6.2 / 26.7. Every rejection introduced or kept by #107437 for explicit strategies remains in force, so the inconsistency from #106465 does not come back: the implicit case is not "silently accepted as hive", it deterministically resolves towildcard— the same table you would get on any pre-26.6 server.Why this matters
CREATE TABLE ... ENGINE = S3('.../{_partition_id}.native', ...) PARTITION BY ...is a long-standing documented pattern; it is emitted by existing DDL generators (for example, orchestration tooling that provisions system log tables with object storage). After #107437 (26.7.1.1258, backported to 26.6.2.92) suchCREATEstatements fail withBAD_ARGUMENTSwithin a stable release series. Since onlyCREATEis affected (ATTACH/startup infer from path shape), running tables survive the upgrade but any re-provisioning breaks — the worst kind of surprise. This PR should be backported to 26.6.Tests
04337_s3_hive_partition_id_compatibility_validation.sql(from Fix hive partition validation when compatibility is 26.6 #107437) updated: the implicit +{_partition_id}+compatibility = '26.6'case now expects success, and an explicit-hiverejection case was added; the ATTACH regression cases are unchanged.04614_implicit_wildcard_partition_strategy_from_path.sql: write/read round-trip through an implicit-wildcard table under thehivedefault,DETACH/ATTACHsurvival, explicit-hiverejection on the same path, and the table-functionINSERT INTO FUNCTION s3(...) PARTITION BYcase.Version info
26.8.1.120(included in26.8and later)26.7.2.19,26.6.2.116