summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvitya-smirnov <[email protected]>2026-07-22 13:56:33 +0300
committervitya-smirnov <[email protected]>2026-07-22 15:55:55 +0300
commitbcaa294d753a1885accabda694f31d01faa4f5a3 (patch)
tree3d6e0c07dee724b1a74f1af5c815e7bd3fbfc3b6
parent06fe1bd4771edb10d2193f404c7dbe5f86db4937 (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.cpp10
-rw-r--r--yql/essentials/core/langver/feature.gen.py4
-rw-r--r--yql/essentials/core/langver/feature.h20
-rw-r--r--yql/essentials/data/language/features.json3
-rw-r--r--yql/essentials/public/langver/yql_langver.cpp10
-rw-r--r--yql/essentials/public/langver/yql_langver.h11
-rw-r--r--yql/essentials/udfs/common/datetime2/datetime_udf.cpp4
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>>,