diff options
| author | vitya-smirnov <[email protected]> | 2026-07-22 13:56:33 +0300 |
|---|---|---|
| committer | vitya-smirnov <[email protected]> | 2026-07-22 15:55:55 +0300 |
| commit | bcaa294d753a1885accabda694f31d01faa4f5a3 (patch) | |
| tree | 3d6e0c07dee724b1a74f1af5c815e7bd3fbfc3b6 | |
| parent | 06fe1bd4771edb10d2193f404c7dbe5f86db4937 (diff) | |
YQL-21408: Make TFeature constexpr
#### Make TFeature constexpr and enhance langversion validation ✎
- Refactored `TFeature` to be fully `constexpr` by removing the `Finish()` method and introducing a `Checked()` static method for compile-time validation of language version ranges.
- Updated feature generation logic to initialize features as `inline constexpr` with direct validation during compilation.
- Moved `IsValidLangVersion` implementation to header file and made it `constexpr` for compile-time checks.
- Added new feature `Interval64Seconds` with minimum language version `2025.03`.
- Updated code to use the new `Interval64Seconds` feature for conditional compilation instead of hardcoded version numbers.
<a href="https://nda.ya.ru/t/qa0kX64r7DqvtN"><font size="2">Autodescription by Yandex Code Assistant</font></a>
commit_hash:504d387ebb1cc3958ee0e916cfc3e83691c756fe
| -rw-r--r-- | yql/essentials/core/langver/feature.cpp | 10 | ||||
| -rw-r--r-- | yql/essentials/core/langver/feature.gen.py | 4 | ||||
| -rw-r--r-- | yql/essentials/core/langver/feature.h | 20 | ||||
| -rw-r--r-- | yql/essentials/data/language/features.json | 3 | ||||
| -rw-r--r-- | yql/essentials/public/langver/yql_langver.cpp | 10 | ||||
| -rw-r--r-- | yql/essentials/public/langver/yql_langver.h | 11 | ||||
| -rw-r--r-- | yql/essentials/udfs/common/datetime2/datetime_udf.cpp | 4 |
7 files changed, 32 insertions, 30 deletions
diff --git a/yql/essentials/core/langver/feature.cpp b/yql/essentials/core/langver/feature.cpp index db9b7659e8b..4224a64036c 100644 --- a/yql/essentials/core/langver/feature.cpp +++ b/yql/essentials/core/langver/feature.cpp @@ -45,16 +45,6 @@ std::expected<std::monostate, TError> GetAvailability( } // namespace -TFeature TFeature::Finish() && { - YQL_ENSURE( - MinLangVer == UnknownLangVersion || IsValidLangVersion(MinLangVer), - "LangVer: " << FormatLangVersion(MinLangVer)); - YQL_ENSURE( - MaxLangVer == UnknownLangVersion || IsValidLangVersion(MaxLangVer), - "LangVer: " << FormatLangVersion(MaxLangVer)); - return *this; -} - bool IsAvailableOn( TLangVersion current, EBackportCompatibleFeaturesMode mode, diff --git a/yql/essentials/core/langver/feature.gen.py b/yql/essentials/core/langver/feature.gen.py index 4f1fa5ba585..ece5a8a75bc 100644 --- a/yql/essentials/core/langver/feature.gen.py +++ b/yql/essentials/core/langver/feature.gen.py @@ -54,12 +54,12 @@ def emit_feature(name: str, attrs: dict[str, Any]) -> Generator[str]: min_langver = parse_langver(attrs.get("min_langver", "unknown")) max_langver = parse_langver(attrs.get("max_langver", "unknown")) - yield f'const TFeature {name} = (TFeature{{' + yield f'inline constexpr TFeature {name} = TFeature::Checked({{' yield f' .Name = "{name}",' yield f' .Description = "{description}",' yield f' .MinLangVer = {min_langver},' yield f' .MaxLangVer = {max_langver},' - yield f'}}).Finish();' + yield f'}});' yield "" diff --git a/yql/essentials/core/langver/feature.h b/yql/essentials/core/langver/feature.h index 48a6c9d5ad1..a97df4a9634 100644 --- a/yql/essentials/core/langver/feature.h +++ b/yql/essentials/core/langver/feature.h @@ -7,12 +7,22 @@ namespace NYql { struct TFeature { - TString Name; - TString Description; - TLangVersion MinLangVer = UnknownLangVersion; - TLangVersion MaxLangVer = UnknownLangVersion; + const TStringBuf Name; + const TStringBuf Description; + const TLangVersion MinLangVer = UnknownLangVersion; + const TLangVersion MaxLangVer = UnknownLangVersion; - TFeature Finish() &&; + static consteval TFeature Checked(TFeature f) { + if (f.MinLangVer != UnknownLangVersion && !IsValidLangVersion(f.MinLangVer)) { + throw std::invalid_argument("Bad MinLangVer"); + } + + if (f.MaxLangVer != UnknownLangVersion && !IsValidLangVersion(f.MaxLangVer)) { + throw std::invalid_argument("Bad MaxLangVer"); + } + + return f; + } }; bool IsAvailableOn( diff --git a/yql/essentials/data/language/features.json b/yql/essentials/data/language/features.json index 1cb27b27cb6..d96fd7ad201 100644 --- a/yql/essentials/data/language/features.json +++ b/yql/essentials/data/language/features.json @@ -147,6 +147,9 @@ "ValidateRegexp": { "min_langver": "2025.03" }, + "Interval64Seconds": { + "min_langver": "2025.03" + }, "GroupByExprAfterWhere": { "min_langver": "2025.02" }, diff --git a/yql/essentials/public/langver/yql_langver.cpp b/yql/essentials/public/langver/yql_langver.cpp index 042584e5cc6..a7f5a6d79da 100644 --- a/yql/essentials/public/langver/yql_langver.cpp +++ b/yql/essentials/public/langver/yql_langver.cpp @@ -13,16 +13,6 @@ constexpr TLangVersion MaxReleasedLangVersion = MakeLangVersion(2026, 1); } // namespace -bool IsValidLangVersion(TLangVersion ver) { - for (const auto& version : Versions) { - if (ver == MakeLangVersion(version.first, version.second)) { - return true; - } - } - - return false; -} - bool ParseLangVersion(TStringBuf str, TLangVersion& result) { result = UnknownLangVersion; if (str.size() != 7 || str[4] != '.') { diff --git a/yql/essentials/public/langver/yql_langver.h b/yql/essentials/public/langver/yql_langver.h index f9631c88b72..939cde3e5e8 100644 --- a/yql/essentials/public/langver/yql_langver.h +++ b/yql/essentials/public/langver/yql_langver.h @@ -54,6 +54,16 @@ constexpr inline bool IsUnsupportedLangVersion(TLangVersion ver, TLangVersion ma return GetYearFromLangVersion(ver) <= GetYearFromLangVersion(max) - 3; } +constexpr bool IsValidLangVersion(TLangVersion ver) { + for (const auto& version : Versions) { + if (ver == MakeLangVersion(version.first, version.second)) { + return true; + } + } + + return false; +} + constexpr TLangVersion MinLangVersion = MakeLangVersion(2025, 1); TLangVersion GetMaxReleasedLangVersion(); @@ -71,7 +81,6 @@ constexpr TLangVersion GetMaxLangVersion() { constexpr ui32 LangVersionBufferSize = 4 + 1 + 2 + 1; // year.minor\0 using TLangVersionBuffer = std::array<char, LangVersionBufferSize>; -bool IsValidLangVersion(TLangVersion ver); bool ParseLangVersion(TStringBuf str, TLangVersion& result); bool FormatLangVersion(TLangVersion ver, TLangVersionBuffer& buffer, TStringBuf& result); TMaybe<TString> FormatLangVersion(TLangVersion ver); diff --git a/yql/essentials/udfs/common/datetime2/datetime_udf.cpp b/yql/essentials/udfs/common/datetime2/datetime_udf.cpp index 50b70cc59d8..8841743ebb1 100644 --- a/yql/essentials/udfs/common/datetime2/datetime_udf.cpp +++ b/yql/essentials/udfs/common/datetime2/datetime_udf.cpp @@ -3752,7 +3752,7 @@ SIMPLE_MODULE(TDateTime2Module, TIntervalFromMinutes, TLangVerForked< - NYql::MakeLangVersion(2025, 03), // TODO(YQL-21408) + NYql::NFeature::Interval64Seconds.MinLangVer, NLegacy::TIntervalFromSeconds, NActual::TIntervalFromSeconds>, @@ -3802,7 +3802,7 @@ SIMPLE_MODULE(TDateTime2Module, SimpleDatetimeToIntervalUdf<TM64ResourceName, EndOf<TTM64Storage>>>, TLangVerForked< - NYql::MakeLangVersion(2025, 03), // TODO(YQL-21408) + NYql::NFeature::Interval64Seconds.MinLangVer, TToUnits<ToSecondsUDF, /* TResult = */ ui32, /* TSignedResult = */ i32, /* TWResult = */ i64, 1>, TToUnits<ToSecondsUDF, /* TResult = */ ui32, /* TSignedResult = */ i64, /* TWResult = */ i64, 1>>, |
