@@ -612,6 +612,225 @@ order by SessionId;)", "%Y-%m-%d %H:%M:%S %Z", sessionsSet.front().GetId().data(
612612 UNIT_ASSERT_VALUES_EQUAL (nodeIds[4 ], offset);
613613 }
614614
615+ Y_UNIT_TEST (PartitionStatsOrderByDesc) {
616+ // Test ORDER BY DESC for partition_stats sys view
617+ TKikimrRunner kikimr;
618+ auto client = kikimr.GetQueryClient ();
619+ auto session = client.GetSession ().GetValueSync ().GetSession ();
620+
621+ const auto describeResult = kikimr.GetTestClient ().Describe (
622+ kikimr.GetTestServer ().GetRuntime (), " /Root/EightShard" );
623+
624+ auto result = session.ExecuteQuery (R"( --!syntax_v1
625+ SELECT PathId, PartIdx, Path
626+ FROM `/Root/.sys/partition_stats`
627+ ORDER BY PathId DESC, PartIdx DESC
628+ )" , NYdb::NQuery::TTxControl::NoTx ()).GetValueSync ();
629+
630+ UNIT_ASSERT_C (result.IsSuccess (), result.GetIssues ().ToString ());
631+
632+ // Collect all results
633+ TVector<std::pair<ui64, ui64>> pathIdPartIdx;
634+ auto resultSet = result.GetResultSet (0 );
635+ NYdb::TResultSetParser parser (resultSet);
636+ while (parser.TryNextRow ()) {
637+ auto pathId = parser.ColumnParser (" PathId" ).GetOptionalUint64 ().value ();
638+ auto partIdx = parser.ColumnParser (" PartIdx" ).GetOptionalUint64 ().value ();
639+ pathIdPartIdx.push_back ({pathId, partIdx});
640+ }
641+
642+ // Verify we got some results
643+ UNIT_ASSERT_C (pathIdPartIdx.size () > 0 , " Expected at least one partition" );
644+
645+ // Verify results are in descending order by PathId, then PartIdx
646+ for (size_t i = 1 ; i < pathIdPartIdx.size (); ++i) {
647+ const auto & prev = pathIdPartIdx[i - 1 ];
648+ const auto & curr = pathIdPartIdx[i];
649+
650+ bool isOrdered = (prev.first > curr.first ) ||
651+ (prev.first == curr.first && prev.second >= curr.second );
652+
653+ UNIT_ASSERT_C (isOrdered,
654+ TStringBuilder () << " Results not in descending order: "
655+ << " pathIdPartIdx[" << (i - 1 ) << " ] = (" << prev.first << " , " << prev.second << " )"
656+ << " > pathIdPartIdx[" << i << " ] = (" << curr.first << " , " << curr.second << " )"
657+ << " . ORDER BY DESC is being ignored by sys view actors." );
658+ }
659+ }
660+
661+ Y_UNIT_TEST (QuerySessionsOrderByDesc) {
662+ // Test ORDER BY DESC for query_sessions sys view
663+ NKikimrConfig::TFeatureFlags featureFlags;
664+ featureFlags.SetEnableRealSystemViewPaths (true );
665+ TKikimrSettings settings;
666+ settings.SetWithSampleTables (false );
667+ settings.SetFeatureFlags (featureFlags);
668+ settings.SetAuthToken (" root@builtin" );
669+ TKikimrRunner kikimr (settings);
670+
671+ auto client = kikimr.GetQueryClient ();
672+ auto session = client.GetSession ().GetValueSync ().GetSession ();
673+
674+ // Create some sessions to have data
675+ const size_t sessionsCount = 5 ;
676+ std::vector<NYdb::NQuery::TSession> sessionsSet;
677+ for (ui32 i = 0 ; i < sessionsCount; i++) {
678+ sessionsSet.emplace_back (std::move (client.GetSession ().GetValueSync ().GetSession ()));
679+ }
680+
681+ // Wait a bit for sessions to be registered
682+ ::Sleep (TDuration::MilliSeconds(100 ));
683+
684+ auto result = session.ExecuteQuery (R"( --!syntax_v1
685+ SELECT SessionId, State, NodeId
686+ FROM `/Root/.sys/query_sessions`
687+ ORDER BY SessionId DESC
688+ )" , NYdb::NQuery::TTxControl::NoTx ()).GetValueSync ();
689+
690+ UNIT_ASSERT_C (result.IsSuccess (), result.GetIssues ().ToString ());
691+
692+ // Collect all results
693+ TVector<std::string> sessionIds;
694+ auto resultSet = result.GetResultSet (0 );
695+ NYdb::TResultSetParser parser (resultSet);
696+ while (parser.TryNextRow ()) {
697+ auto sessionId = parser.ColumnParser (" SessionId" ).GetOptionalUtf8 ().value ();
698+ sessionIds.push_back (sessionId);
699+ }
700+
701+ // Verify we got some results
702+ UNIT_ASSERT_C (sessionIds.size () > 0 , " Expected at least one session" );
703+
704+ // Verify results are in descending order (lexicographically)
705+ for (size_t i = 1 ; i < sessionIds.size (); ++i) {
706+ UNIT_ASSERT_C (sessionIds[i - 1 ] >= sessionIds[i],
707+ TStringBuilder () << " Results not in descending order: "
708+ << " sessionIds[" << (i - 1 ) << " ] = \" " << sessionIds[i - 1 ] << " \" "
709+ << " < sessionIds[" << i << " ] = \" " << sessionIds[i] << " \" "
710+ << " . ORDER BY DESC is being ignored by sys view actors." );
711+ }
712+ }
713+
714+ Y_UNIT_TEST (CompileCacheQueriesOrderByDesc) {
715+ // Test ORDER BY DESC for compile_cache_queries sys view
716+ auto serverSettings = TKikimrSettings ().SetKqpSettings ({ NKikimrKqp::TKqpSetting () });
717+ serverSettings.AppConfig .MutableTableServiceConfig ()->SetEnableImplicitQueryParameterTypes (true );
718+ TKikimrRunner kikimr (serverSettings);
719+ kikimr.GetTestServer ().GetRuntime ()->GetAppData ().FeatureFlags .SetEnableCompileCacheView (true );
720+ auto client = kikimr.GetQueryClient ();
721+ auto session = client.GetSession ().GetValueSync ().GetSession ();
722+
723+ // Execute some queries to populate compile cache
724+ auto tableClient = kikimr.GetTableClient ();
725+ for (ui32 i = 0 ; i < 3 ; ++i) {
726+ auto tableSession = tableClient.CreateSession ().GetValueSync ().GetSession ();
727+ auto paramsBuilder = TParamsBuilder ();
728+ paramsBuilder.AddParam (" $k" ).Uint64 (i).Build ();
729+ auto executedResult = tableSession.ExecuteDataQuery (
730+ R"( DECLARE $k AS Uint64;
731+ SELECT COUNT(*) FROM `/Root/EightShard` WHERE Key = $k;)" ,
732+ TTxControl::BeginTx ().CommitTx (),
733+ paramsBuilder.Build ()
734+ ).GetValueSync ();
735+ UNIT_ASSERT_C (executedResult.IsSuccess (), executedResult.GetIssues ().ToString ());
736+ }
737+
738+ // Wait a bit for compile cache to be updated
739+ ::Sleep (TDuration::MilliSeconds(100 ));
740+
741+ auto result = session.ExecuteQuery (R"( --!syntax_v1
742+ SELECT QueryText, CompilationDuration
743+ FROM `/Root/.sys/compile_cache_queries`
744+ ORDER BY QueryText DESC
745+ )" , NYdb::NQuery::TTxControl::NoTx ()).GetValueSync ();
746+
747+ UNIT_ASSERT_C (result.IsSuccess (), result.GetIssues ().ToString ());
748+
749+ // Collect all results
750+ TVector<std::string> queryTexts;
751+ auto resultSet = result.GetResultSet (0 );
752+ NYdb::TResultSetParser parser (resultSet);
753+ while (parser.TryNextRow ()) {
754+ auto queryText = parser.ColumnParser (" QueryText" ).GetOptionalUtf8 ().value ();
755+ queryTexts.push_back (queryText);
756+ }
757+
758+ // Verify we got some results
759+ if (queryTexts.size () > 0 ) {
760+ // Verify results are in descending order (lexicographically)
761+ for (size_t i = 1 ; i < queryTexts.size (); ++i) {
762+ UNIT_ASSERT_C (queryTexts[i - 1 ] >= queryTexts[i],
763+ TStringBuilder () << " Results not in descending order: "
764+ << " queryTexts[" << (i - 1 ) << " ] = \" " << queryTexts[i - 1 ] << " \" "
765+ << " < queryTexts[" << i << " ] = \" " << queryTexts[i] << " \" "
766+ << " . ORDER BY DESC is being ignored by sys view actors." );
767+ }
768+ }
769+ }
770+
771+ Y_UNIT_TEST (TopQueriesOrderByDesc) {
772+ // Test ORDER BY DESC for top_queries sys views
773+ TKikimrRunner kikimr (" " , KikimrDefaultUtDomainRoot, 3 );
774+ auto client = kikimr.GetQueryClient ();
775+ auto session = client.GetSession ().GetValueSync ().GetSession ();
776+
777+ // Execute some queries to populate stats
778+ auto tableClient = kikimr.GetTableClient ();
779+ auto tableSession = tableClient.CreateSession ().GetValueSync ().GetSession ();
780+ {
781+ auto result = tableSession.ExecuteDataQuery (Q_ (R"(
782+ SELECT * FROM `/Root/TwoShard`
783+ )" ), TTxControl::BeginTx ().CommitTx ()).GetValueSync ();
784+ UNIT_ASSERT_VALUES_EQUAL (result.GetStatus (), EStatus::SUCCESS);
785+ }
786+ {
787+ auto result = tableSession.ExecuteDataQuery (Q_ (R"(
788+ SELECT * FROM `/Root/EightShard`
789+ )" ), TTxControl::BeginTx ().CommitTx ()).GetValueSync ();
790+ UNIT_ASSERT_VALUES_EQUAL (result.GetStatus (), EStatus::SUCCESS);
791+ }
792+
793+ // Wait a bit for stats to be collected
794+ ::Sleep (TDuration::MilliSeconds(500 ));
795+
796+ // Test top_queries_by_read_bytes_one_minute
797+ auto result = session.ExecuteQuery (R"( --!syntax_v1
798+ SELECT IntervalEnd, Rank, ReadBytes
799+ FROM `/Root/.sys/top_queries_by_read_bytes_one_minute`
800+ ORDER BY IntervalEnd DESC, Rank DESC
801+ )" , NYdb::NQuery::TTxControl::NoTx ()).GetValueSync ();
802+
803+ UNIT_ASSERT_C (result.IsSuccess (), result.GetIssues ().ToString ());
804+
805+ // Collect all results
806+ TVector<std::pair<TInstant, ui32>> intervalEndRank;
807+ auto resultSet = result.GetResultSet (0 );
808+ NYdb::TResultSetParser parser (resultSet);
809+ while (parser.TryNextRow ()) {
810+ auto intervalEnd = parser.ColumnParser (" IntervalEnd" ).GetOptionalTimestamp ().value ();
811+ auto rank = parser.ColumnParser (" Rank" ).GetOptionalUint32 ().value ();
812+ intervalEndRank.push_back ({intervalEnd, rank});
813+ }
814+
815+ // Verify we got some results (may be empty if no stats collected yet)
816+ if (intervalEndRank.size () > 0 ) {
817+ // Verify results are in descending order by IntervalEnd, then Rank
818+ for (size_t i = 1 ; i < intervalEndRank.size (); ++i) {
819+ const auto & prev = intervalEndRank[i - 1 ];
820+ const auto & curr = intervalEndRank[i];
821+
822+ bool isOrdered = (prev.first > curr.first ) ||
823+ (prev.first == curr.first && prev.second >= curr.second );
824+
825+ UNIT_ASSERT_C (isOrdered,
826+ TStringBuilder () << " Results not in descending order: "
827+ << " intervalEndRank[" << (i - 1 ) << " ] = (" << prev.first .ToString () << " , " << prev.second << " )"
828+ << " > intervalEndRank[" << i << " ] = (" << curr.first .ToString () << " , " << curr.second << " )"
829+ << " . ORDER BY DESC is being ignored by sys view actors." );
830+ }
831+ }
832+ }
833+
615834 Y_UNIT_TEST (QueryStatsSimple) {
616835 auto checkTable = [&] (const TStringBuf tableName) {
617836 TKikimrRunner kikimr (" " , KikimrDefaultUtDomainRoot, 3 );
0 commit comments