@@ -132,6 +132,8 @@ bool ConvertCreateTableSettingsToProto(NYql::TKikimrTableMetadataPtr metadata, Y
132132 familyProto->set_compression (Ydb::Table::ColumnFamily::COMPRESSION_NONE);
133133 } else if (to_lower (family.Compression .GetRef ()) == " lz4" ) {
134134 familyProto->set_compression (Ydb::Table::ColumnFamily::COMPRESSION_LZ4);
135+ } else if (to_lower (family.Compression .GetRef ()) == " zstd" ) {
136+ familyProto->set_compression (Ydb::Table::ColumnFamily::COMPRESSION_ZSTD);
135137 } else {
136138 code = Ydb::StatusIds::BAD_REQUEST;
137139 error = TStringBuilder () << " Unknown compression '" << family.Compression .GetRef () << " ' for a column family" ;
@@ -383,9 +385,59 @@ bool FillCreateTableDesc(NYql::TKikimrTableMetadataPtr metadata, NKikimrSchemeOp
383385}
384386
385387template <typename T>
386- void FillColumnTableSchema (NKikimrSchemeOp::TColumnTableSchema& schema, const T& metadata)
387- {
388+ bool FillColumnTableSchema (NKikimrSchemeOp::TColumnTableSchema& schema, const T& metadata, Ydb::StatusIds::StatusCode& code, TString& error) {
388389 Y_ENSURE (metadata.ColumnOrder .size () == metadata.Columns .size ());
390+
391+ THashMap<TString, ui32> columnFamiliesByName;
392+ ui32 columnFamilyId = 1 ;
393+ for (const auto & family : metadata.ColumnFamilies ) {
394+ if (family.Data .Defined ()) {
395+ code = Ydb::StatusIds::BAD_REQUEST;
396+ error = TStringBuilder () << " Field `DATA` is not supported for OLAP tables in column family '" << family.Name << " '" ;
397+ return false ;
398+ }
399+ auto columnFamilyIt = columnFamiliesByName.find (family.Name );
400+ if (!columnFamilyIt.IsEnd ()) {
401+ code = Ydb::StatusIds::BAD_REQUEST;
402+ error = TStringBuilder () << " Duplicate column family `" << family.Name << ' `' ;
403+ return false ;
404+ }
405+ auto familyDescription = schema.AddColumnFamilies ();
406+ familyDescription->SetName (family.Name );
407+ if (familyDescription->GetName () == " default" ) {
408+ familyDescription->SetId (0 );
409+ } else {
410+ familyDescription->SetId (columnFamilyId++);
411+ }
412+ Y_ENSURE (columnFamiliesByName.emplace (familyDescription->GetName (), familyDescription->GetId ()).second );
413+ if (family.Compression .Defined ()) {
414+ NKikimrSchemeOp::EColumnCodec codec;
415+ auto codecName = to_lower (family.Compression .GetRef ());
416+ if (codecName == " off" ) {
417+ codec = NKikimrSchemeOp::EColumnCodec::ColumnCodecPlain;
418+ } else if (codecName == " zstd" ) {
419+ codec = NKikimrSchemeOp::EColumnCodec::ColumnCodecZSTD;
420+ } else if (codecName == " lz4" ) {
421+ codec = NKikimrSchemeOp::EColumnCodec::ColumnCodecLZ4;
422+ } else {
423+ code = Ydb::StatusIds::BAD_REQUEST;
424+ error = TStringBuilder () << " Unknown compression '" << family.Compression .GetRef () << " ' for a column family" ;
425+ return false ;
426+ }
427+ familyDescription->SetColumnCodec (codec);
428+ } else {
429+ code = Ydb::StatusIds::BAD_REQUEST;
430+ error = TStringBuilder () << " Compression is not set for column family'" << family.Name << " '" ;
431+ return false ;
432+ }
433+
434+ if (family.CompressionLevel .Defined ()) {
435+ familyDescription->SetColumnCodecLevel (family.CompressionLevel .GetRef ());
436+ }
437+ }
438+
439+ schema.SetNextColumnFamilyId (columnFamilyId);
440+
389441 for (const auto & name : metadata.ColumnOrder ) {
390442 auto columnIt = metadata.Columns .find (name);
391443 Y_ENSURE (columnIt != metadata.Columns .end ());
@@ -399,11 +451,29 @@ void FillColumnTableSchema(NKikimrSchemeOp::TColumnTableSchema& schema, const T&
399451 if (columnType.TypeInfo ) {
400452 *columnDesc.MutableTypeInfo () = *columnType.TypeInfo ;
401453 }
454+
455+ if (!columnFamiliesByName.empty ()) {
456+ TString columnFamilyName = " default" ;
457+ ui32 columnFamilyId = 0 ;
458+ if (columnIt->second .Families .size ()) {
459+ columnFamilyName = *columnIt->second .Families .begin ();
460+ auto columnFamilyIdIt = columnFamiliesByName.find (columnFamilyName);
461+ if (columnFamilyIdIt.IsEnd ()) {
462+ code = Ydb::StatusIds::BAD_REQUEST;
463+ error = TStringBuilder () << " Unknown column family `" << columnFamilyName << " ` for column `" << columnDesc.GetName () << " `" ;
464+ return false ;
465+ }
466+ columnFamilyId = columnFamilyIdIt->second ;
467+ }
468+ columnDesc.SetColumnFamilyName (columnFamilyName);
469+ columnDesc.SetColumnFamilyId (columnFamilyId);
470+ }
402471 }
403472
404473 for (const auto & keyColumn : metadata.KeyColumnNames ) {
405474 schema.AddKeyColumnNames (keyColumn);
406475 }
476+ return true ;
407477}
408478
409479bool FillCreateColumnTableDesc (NYql::TKikimrTableMetadataPtr metadata,
@@ -1705,7 +1775,12 @@ class TKqpGatewayProxy : public IKikimrGateway {
17051775 NKikimrSchemeOp::TColumnTableDescription* tableDesc = schemeTx.MutableCreateColumnTable ();
17061776
17071777 tableDesc->SetName (pathPair.second );
1708- FillColumnTableSchema (*tableDesc->MutableSchema (), *metadata);
1778+ if (!FillColumnTableSchema (*tableDesc->MutableSchema (), *metadata, code, error)) {
1779+ IKqpGateway::TGenericResult errResult;
1780+ errResult.AddIssue (NYql::TIssue (error));
1781+ errResult.SetStatus (NYql::YqlStatusFromYdbStatus (code));
1782+ return MakeFuture (std::move (errResult));
1783+ }
17091784
17101785 if (!FillCreateColumnTableDesc (metadata, *tableDesc, code, error)) {
17111786 IKqpGateway::TGenericResult errResult;
@@ -2016,7 +2091,22 @@ class TKqpGatewayProxy : public IKikimrGateway {
20162091
20172092 NKikimrSchemeOp::TColumnTableSchemaPreset* schemaPreset = storeDesc->AddSchemaPresets ();
20182093 schemaPreset->SetName (" default" );
2019- FillColumnTableSchema (*schemaPreset->MutableSchema (), settings);
2094+
2095+ if (!settings.ColumnFamilies .empty ()) {
2096+ IKqpGateway::TGenericResult errResult;
2097+ errResult.AddIssue (NYql::TIssue (" TableStore does not support column families" ));
2098+ errResult.SetStatus (NYql::YqlStatusFromYdbStatus (Ydb::StatusIds::BAD_REQUEST));
2099+ return MakeFuture (std::move (errResult));
2100+ }
2101+
2102+ Ydb::StatusIds::StatusCode code;
2103+ TString error;
2104+ if (!FillColumnTableSchema (*schemaPreset->MutableSchema (), settings, code, error)) {
2105+ IKqpGateway::TGenericResult errResult;
2106+ errResult.AddIssue (NYql::TIssue (error));
2107+ errResult.SetStatus (NYql::YqlStatusFromYdbStatus (code));
2108+ return MakeFuture (std::move (errResult));
2109+ }
20202110
20212111 if (IsPrepare ()) {
20222112 auto & phyQuery = *SessionCtx->Query ().PreparingQuery ->MutablePhysicalQuery ();
0 commit comments