diff --git a/ydb/library/yql/sql/v1/SQLv1.g.in b/ydb/library/yql/sql/v1/SQLv1.g.in index 9957d7144a59..a3c2f3227801 100644 --- a/ydb/library/yql/sql/v1/SQLv1.g.in +++ b/ydb/library/yql/sql/v1/SQLv1.g.in @@ -716,18 +716,20 @@ table_constraint: ; table_index: INDEX an_id table_index_type - (WITH LPAREN an_id EQUALS an_id (COMMA an_id EQUALS an_id)* COMMA? RPAREN)? + with_index_settings? ON LPAREN an_id_schema (COMMA an_id_schema)* RPAREN (COVER LPAREN an_id_schema (COMMA an_id_schema)* RPAREN)?; -table_index_type: - global_index - | local_index -; +table_index_type: (global_index | local_index) (USING index_subtype)?; global_index: GLOBAL UNIQUE? (SYNC | ASYNC)?; local_index: LOCAL; +index_subtype: an_id; + +with_index_settings: WITH LPAREN index_settings_entry (COMMA index_settings_entry)* RPAREN; +index_settings_entry: an_id EQUALS an_id; + changefeed: CHANGEFEED an_id WITH LPAREN changefeed_settings RPAREN; changefeed_settings: changefeed_settings_entry (COMMA changefeed_settings_entry)*; changefeed_settings_entry: an_id EQUALS changefeed_setting_value; diff --git a/ydb/library/yql/sql/v1/node.h b/ydb/library/yql/sql/v1/node.h index 66a92cd38fee..0b44e41b1df2 100644 --- a/ydb/library/yql/sql/v1/node.h +++ b/ydb/library/yql/sql/v1/node.h @@ -1144,11 +1144,50 @@ namespace NSQLTranslationV1 { TNodePtr Compression; }; + struct TVectorIndexSettings { + enum class EDistance { + Cosine, + Manhattan, + Euclidean + }; + + enum class ESimilarity { + Cosine, + InnerProduct + }; + + enum class EVectorType { + Float, + Uint8, + Int8, + Bit + }; + + TVectorIndexSettings(EDistance distance, EVectorType vectorType, ui32 vectorDimension) + : Metric(distance) + , VectorType(vectorType) + , VectorDimension(vectorDimension) + {} + + TVectorIndexSettings(ESimilarity similarity, EVectorType vectorType, ui32 vectorDimension) + : Metric(similarity) + , VectorType(vectorType) + , VectorDimension(vectorDimension) + {} + + using TMetric = std::variant; + + TMetric Metric; + EVectorType VectorType; + ui32 VectorDimension; + }; + struct TIndexDescription { enum class EType { GlobalSync, GlobalAsync, GlobalSyncUnique, + GlobalVectorKmeansTree }; TIndexDescription(const TIdentifier& name, EType type = EType::GlobalSync) @@ -1156,11 +1195,15 @@ namespace NSQLTranslationV1 { , Type(type) {} + TIdentifier Name; EType Type; TVector IndexColumns; TVector DataColumns; TTableSettings TableSettings; + + using TIndexSettings = std::variant; + TIndexSettings IndexSettings; }; struct TChangefeedSettings { diff --git a/ydb/library/yql/sql/v1/query.cpp b/ydb/library/yql/sql/v1/query.cpp index e13803eefe27..7dbebf76c842 100644 --- a/ydb/library/yql/sql/v1/query.cpp +++ b/ydb/library/yql/sql/v1/query.cpp @@ -149,6 +149,8 @@ static INode::TPtr CreateIndexType(TIndexDescription::EType type, const INode& n return node.Q("asyncGlobal"); case TIndexDescription::EType::GlobalSyncUnique: return node.Q("syncGlobalUnique"); + case TIndexDescription::EType::GlobalVectorKmeansTree: + return node.Q("globalVectorKmeansTree"); } } diff --git a/ydb/library/yql/sql/v1/sql_translation.cpp b/ydb/library/yql/sql/v1/sql_translation.cpp index ce2670030fe3..26a1b66bda46 100644 --- a/ydb/library/yql/sql/v1/sql_translation.cpp +++ b/ydb/library/yql/sql/v1/sql_translation.cpp @@ -630,10 +630,11 @@ bool PureColumnOrNamedListStr(const TRule_pure_column_or_named_list& node, TTran bool CreateTableIndex(const TRule_table_index& node, TTranslation& ctx, TVector& indexes) { indexes.emplace_back(IdEx(node.GetRule_an_id2(), ctx)); - const auto& indexType = node.GetRule_table_index_type3(); + const auto& indexType = node.GetRule_table_index_type3().GetBlock1(); switch (indexType.Alt_case()) { - case TRule_table_index_type::kAltTableIndexType1: { - auto globalIndex = indexType.GetAlt_table_index_type1().GetRule_global_index1(); + // "GLOBAL" + case TRule_table_index_type_TBlock1::kAlt1: { + auto globalIndex = indexType.GetAlt1().GetRule_global_index1(); bool uniqIndex = false; if (globalIndex.HasBlock2()) { uniqIndex = true; @@ -658,16 +659,39 @@ bool CreateTableIndex(const TRule_table_index& node, TTranslation& ctx, TVector< } } break; - case TRule_table_index_type::kAltTableIndexType2: + // "LOCAL" + case TRule_table_index_type_TBlock1::kAlt2: ctx.AltNotImplemented("local", indexType); return false; - case TRule_table_index_type::ALT_NOT_SET: + case TRule_table_index_type_TBlock1::ALT_NOT_SET: Y_ABORT("You should change implementation according to grammar changes"); } + if (node.GetRule_table_index_type3().HasBlock2()) { + const TString subType = to_upper(IdEx(node.GetRule_table_index_type3().GetBlock2().GetRule_index_subtype2().GetRule_an_id1(), ctx).Name) ; + if (subType == "VECTOR_KMEANS_TREE") { + if (indexes.back().Type != TIndexDescription::EType::GlobalSync) { + ctx.Error() << subType << " index can only be GLOBAL [SYNC]"; + return false; + } + + indexes.back().Type = TIndexDescription::EType::GlobalVectorKmeansTree; + } else { + ctx.Error() << subType << " index subtype is not supported"; + return false; + } + } + + // WITH if (node.HasBlock4()) { - ctx.AltNotImplemented("with", indexType); - return false; + //const auto& with = node.GetBlock4(); + auto& index = indexes.back(); + if (index.Type == TIndexDescription::EType::GlobalVectorKmeansTree) { + + } else { + ctx.AltNotImplemented("with", indexType); + return false; + } } indexes.back().IndexColumns.emplace_back(IdEx(node.GetRule_an_id_schema7(), ctx)); diff --git a/ydb/library/yql/sql/v1/sql_translation.h b/ydb/library/yql/sql/v1/sql_translation.h index 09e634511aa9..ee4d9b2e7e6a 100644 --- a/ydb/library/yql/sql/v1/sql_translation.h +++ b/ydb/library/yql/sql/v1/sql_translation.h @@ -103,6 +103,9 @@ bool PureColumnOrNamedListStr(const TRule_pure_column_or_named_list& node, TTran bool CreateTableIndex(const TRule_table_index& node, TTranslation& ctx, TVector& indexes); +bool CreateIndexSettings(const TRule_table_index_TBlock4& settingsNode, TIndexDescription::EType indexType, TIndexDescription::TIndexSettings& indexSettings); +bool CreateIndexSettingsEntry(const TIdentifier& id, const TIdentifier* value, TIndexDescription::EType indexType, TIndexDescription::TIndexSettings& indexSettings); + std::pair TableKeyImpl(const std::pair& nameWithAt, TViewDescription view, TTranslation& ctx); std::pair TableKeyImpl(const TRule_table_key& node, TTranslation& ctx, bool hasAt); diff --git a/ydb/library/yql/sql/v1/sql_ut.cpp b/ydb/library/yql/sql/v1/sql_ut.cpp index 90dae8d2ea58..5f766ebb5591 100644 --- a/ydb/library/yql/sql/v1/sql_ut.cpp +++ b/ydb/library/yql/sql/v1/sql_ut.cpp @@ -2492,9 +2492,28 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) { UNIT_ASSERT(SqlToYql("USE plato; ALTER TABLE table SET (AUTO_PARTITIONING_BY_SIZE = DISABLED)").IsOk()); } + Y_UNIT_TEST(AlterTableAddIndexLocalIsNotSupported) { + ExpectFailWithError("USE plato; ALTER TABLE table ADD INDEX idx GLOBAL WITH (a=b) ON (col)", + "
:1:40: Error: with: alternative is not implemented yet: 723:20: global_index\n"); + } + Y_UNIT_TEST(AlterTableAddIndexWithIsNotSupported) { - ExpectFailWithError("USE plato; ALTER TABLE table ADD INDEX idx LOCAL WITH (a=b, c=d, e=f) ON (col)", - "
:1:40: Error: local: alternative is not implemented yet: 725:7: local_index\n"); + ExpectFailWithError("USE plato; ALTER TABLE table ADD INDEX idx LOCAL ON (col)", + "
:1:40: Error: local: alternative is not implemented yet: 723:35: local_index\n"); + } + + Y_UNIT_TEST(AlterTableAddIndexVector) { + const auto result = SqlToYql(R"(USE plato; + ALTER TABLE table ADD INDEX idx + GLOBAL USING vector_kmeans_tree + WITH (a=b, c=d, e=f) + ON (col) COVER (col))"); + UNIT_ASSERT_C(result.IsOk(), result.Issues.ToString()); + } + + Y_UNIT_TEST(AlterTableAddIndexWithUnknownSubtype) { + ExpectFailWithError("USE plato; ALTER TABLE table ADD INDEX idx GLOBAL USING unknown ON (col)", + "
:1:57: Error: UNKNOWN index subtype is not supported\n"); } Y_UNIT_TEST(AlterTableAlterIndexSetPartitioningIsCorrect) {