@@ -599,206 +599,94 @@ class TxPlanSerializer {
599
599
if (sourceSettings.RangesExpr ().Maybe <TKqlKeyRange>()) {
600
600
auto table = TString (sourceSettings.Table ().Path ());
601
601
auto range = sourceSettings.RangesExpr ().Cast <TKqlKeyRange>();
602
+ Visit (table, range, sourceSettings, planNode);
603
+ return ;
604
+ }
605
+
606
+ const auto table = TString (sourceSettings.Table ().Path ());
607
+ const auto explainPrompt = TKqpReadTableExplainPrompt::Parse (sourceSettings.ExplainPrompt ().Cast ());
602
608
603
- TOperator op;
604
- TTableRead readInfo;
605
-
606
- auto describeBoundary = [this ](const TExprBase& key) {
607
- if (auto param = key.Maybe <TCoParameter>()) {
608
- return param.Cast ().Name ().StringValue ();
609
- }
610
-
611
- if (auto param = key.Maybe <TCoNth>().Tuple ().Maybe <TCoParameter>()) {
612
- if (auto maybeResultBinding = ContainResultBinding (param.Cast ().Name ().StringValue ())) {
613
- auto [txId, resId] = *maybeResultBinding;
614
- if (auto result = GetResult (txId, resId)) {
615
- auto index = FromString<ui32>(key.Cast <TCoNth>().Index ());
616
- Y_ENSURE (index < result->Size ());
617
- return DescribeValue ((*result)[index ]);
618
- }
619
- }
620
- }
621
-
622
- if (auto literal = key.Maybe <TCoUuid>()) {
623
- return NUuid::UuidBytesToString (literal.Cast ().Literal ().StringValue ());
624
- }
625
-
626
- if (auto literal = key.Maybe <TCoDataCtor>()) {
627
- return literal.Cast ().Literal ().StringValue ();
628
- }
629
-
630
- if (auto literal = key.Maybe <TCoNothing>()) {
631
- return TString (" null" );
632
- }
633
-
634
- return TString (" n/a" );
635
- };
636
-
637
- /* Collect info about scan range */
638
- struct TKeyPartRange {
639
- TString From;
640
- TString To;
641
- TString ColumnName;
642
- };
643
- auto & tableData = SerializerCtx.TablesData ->GetTable (SerializerCtx.Cluster , table);
644
- op.Properties [" Table" ] = tableData.RelativePath ? *tableData.RelativePath : table;
645
- planNode.NodeInfo [" Tables" ].AppendValue (op.Properties [" Table" ]);
646
- TVector<TKeyPartRange> scanRangeDescr (tableData.Metadata ->KeyColumnNames .size ());
647
-
648
- auto maybeFromKey = range.From ().Maybe <TKqlKeyTuple>();
649
- auto maybeToKey = range.To ().Maybe <TKqlKeyTuple>();
650
- if (maybeFromKey && maybeToKey) {
651
- auto fromKey = maybeFromKey.Cast ();
652
- auto toKey = maybeToKey.Cast ();
653
-
654
- for (ui32 i = 0 ; i < fromKey.ArgCount (); ++i) {
655
- scanRangeDescr[i].From = describeBoundary (fromKey.Arg (i));
656
- }
657
- for (ui32 i = 0 ; i < toKey.ArgCount (); ++i) {
658
- scanRangeDescr[i].To = describeBoundary (toKey.Arg (i));
659
- }
660
- for (ui32 i = 0 ; i < scanRangeDescr.size (); ++i) {
661
- scanRangeDescr[i].ColumnName = tableData.Metadata ->KeyColumnNames [i];
662
- }
663
-
664
- TString leftParen = range.From ().Maybe <TKqlKeyInc>().IsValid () ? " [" : " (" ;
665
- TString rightParen = range.To ().Maybe <TKqlKeyInc>().IsValid () ? " ]" : " )" ;
666
- bool hasRangeScans = false ;
667
- auto & ranges = op.Properties [" ReadRange" ];
668
- for (const auto & keyPartRange : scanRangeDescr) {
669
- TStringBuilder rangeDescr;
670
-
671
- if (keyPartRange.From == keyPartRange.To ) {
672
- if (keyPartRange.From .Empty ()) {
673
- rangeDescr << keyPartRange.ColumnName << " (-∞, +∞)" ;
674
- readInfo.ScanBy .push_back (rangeDescr);
675
- } else {
676
- rangeDescr << keyPartRange.ColumnName
677
- << " (" << RemoveForbiddenChars (keyPartRange.From ) << " )" ;
678
- readInfo.LookupBy .push_back (rangeDescr);
679
- }
680
- } else {
681
- rangeDescr << keyPartRange.ColumnName << " "
682
- << (keyPartRange.From .Empty () ? " (" : leftParen)
683
- << (keyPartRange.From .Empty () ? " -∞" : RemoveForbiddenChars (keyPartRange.From )) << " , "
684
- << (keyPartRange.To .Empty () ? " +∞" : RemoveForbiddenChars (keyPartRange.To ))
685
- << (keyPartRange.To .Empty () ? " )" : rightParen);
686
- readInfo.ScanBy .push_back (rangeDescr);
687
- hasRangeScans = true ;
688
- }
609
+ TTableRead readInfo;
610
+ TOperator op;
689
611
690
- ranges.AppendValue (rangeDescr);
691
- }
612
+ auto & tableData = SerializerCtx.TablesData ->GetTable (SerializerCtx.Cluster , table);
613
+ op.Properties [" Table" ] = tableData.RelativePath ? *tableData.RelativePath : table;
614
+ planNode.NodeInfo [" Tables" ].AppendValue (op.Properties [" Table" ]);
692
615
693
- if (readInfo.LookupBy .size () > 0 ) {
694
- bool isFullPk = readInfo.LookupBy .size () == tableData.Metadata ->KeyColumnNames .size ();
695
- readInfo.Type = isFullPk ? EPlanTableReadType::Lookup : EPlanTableReadType::Scan;
696
- } else {
697
- readInfo.Type = hasRangeScans ? EPlanTableReadType::Scan : EPlanTableReadType::FullScan;
698
- }
699
- }
616
+ auto rangesDesc = NPlanUtils::PrettyExprStr (sourceSettings.RangesExpr ());
617
+ if (rangesDesc == " Void" || explainPrompt.UsedKeyColumns .empty ()) {
618
+ readInfo.Type = EPlanTableReadType::FullScan;
700
619
701
- auto & columns = op.Properties [" ReadColumns" ];
702
- for (auto const & col : sourceSettings.Columns ()) {
703
- readInfo.Columns .emplace_back (TString (col.Value ()));
704
- columns.AppendValue (col.Value ());
620
+ auto & ranges = op.Properties [" ReadRanges" ];
621
+ for (const auto & col : tableData.Metadata ->KeyColumnNames ) {
622
+ TStringBuilder rangeDesc;
623
+ rangeDesc << col << " (-∞, +∞)" ;
624
+ readInfo.ScanBy .push_back (rangeDesc);
625
+ ranges.AppendValue (rangeDesc);
705
626
}
627
+ } else if (auto maybeResultBinding = ContainResultBinding (rangesDesc)) {
628
+ readInfo.Type = EPlanTableReadType::Scan;
706
629
707
- AddReadTableSettings (op, sourceSettings.Settings (), readInfo);
708
-
709
- AddOptimizerEstimates (op, sourceSettings);
710
-
711
- SerializerCtx.Tables [table].Reads .push_back (readInfo);
712
-
713
- auto readName = GetNameByReadType (readInfo.Type );
714
- op.Properties [" Name" ] = readName;
715
- AddOperator (planNode, readName, std::move (op));
716
- } else {
717
- const auto table = TString (sourceSettings.Table ().Path ());
718
- const auto explainPrompt = TKqpReadTableExplainPrompt::Parse (sourceSettings.ExplainPrompt ().Cast ());
719
-
720
- TTableRead readInfo;
721
- TOperator op;
722
-
723
- auto & tableData = SerializerCtx.TablesData ->GetTable (SerializerCtx.Cluster , table);
724
- op.Properties [" Table" ] = tableData.RelativePath ? *tableData.RelativePath : table;
725
- planNode.NodeInfo [" Tables" ].AppendValue (op.Properties [" Table" ]);
726
-
727
- auto rangesDesc = NPlanUtils::PrettyExprStr (sourceSettings.RangesExpr ());
728
- if (rangesDesc == " Void" || explainPrompt.UsedKeyColumns .empty ()) {
729
- readInfo.Type = EPlanTableReadType::FullScan;
730
-
731
- auto & ranges = op.Properties [" ReadRanges" ];
732
- for (const auto & col : tableData.Metadata ->KeyColumnNames ) {
733
- TStringBuilder rangeDesc;
734
- rangeDesc << col << " (-∞, +∞)" ;
735
- readInfo.ScanBy .push_back (rangeDesc);
736
- ranges.AppendValue (rangeDesc);
737
- }
738
- } else if (auto maybeResultBinding = ContainResultBinding (rangesDesc)) {
739
- readInfo.Type = EPlanTableReadType::Scan;
630
+ auto [txId, resId] = *maybeResultBinding;
631
+ if (auto result = GetResult (txId, resId)) {
632
+ auto ranges = (*result)[0 ];
633
+ const auto & keyColumns = tableData.Metadata ->KeyColumnNames ;
634
+ for (size_t rangeId = 0 ; rangeId < ranges.Size (); ++rangeId) {
635
+ Y_ENSURE (ranges[rangeId].HaveValue () && ranges[rangeId].Size () == 2 );
636
+ auto from = ranges[rangeId][0 ];
637
+ auto to = ranges[rangeId][1 ];
740
638
741
- auto [txId, resId] = *maybeResultBinding;
742
- if (auto result = GetResult (txId, resId)) {
743
- auto ranges = (*result)[0 ];
744
- const auto & keyColumns = tableData.Metadata ->KeyColumnNames ;
745
- for (size_t rangeId = 0 ; rangeId < ranges.Size (); ++rangeId) {
746
- Y_ENSURE (ranges[rangeId].HaveValue () && ranges[rangeId].Size () == 2 );
747
- auto from = ranges[rangeId][0 ];
748
- auto to = ranges[rangeId][1 ];
749
-
750
- for (size_t colId = 0 ; colId < keyColumns.size (); ++colId) {
751
- if (!from[colId].HaveValue () && !to[colId].HaveValue ()) {
752
- continue ;
753
- }
639
+ for (size_t colId = 0 ; colId < keyColumns.size (); ++colId) {
640
+ if (!from[colId].HaveValue () && !to[colId].HaveValue ()) {
641
+ continue ;
642
+ }
754
643
755
- TStringBuilder rangeDesc;
756
- rangeDesc << keyColumns[colId] << " "
757
- << (from[keyColumns.size ()].GetDataText () == " 1" ? " [" : " (" )
758
- << (from[colId].HaveValue () ? RemoveForbiddenChars (from[colId].GetSimpleValueText ()) : " -∞" ) << " , "
759
- << (to[colId].HaveValue () ? RemoveForbiddenChars (to[colId].GetSimpleValueText ()) : " +∞" )
760
- << (to[keyColumns.size ()].GetDataText () == " 1" ? " ]" : " )" );
644
+ TStringBuilder rangeDesc;
645
+ rangeDesc << keyColumns[colId] << " "
646
+ << (from[keyColumns.size ()].GetDataText () == " 1" ? " [" : " (" )
647
+ << (from[colId].HaveValue () ? RemoveForbiddenChars (from[colId].GetSimpleValueText ()) : " -∞" ) << " , "
648
+ << (to[colId].HaveValue () ? RemoveForbiddenChars (to[colId].GetSimpleValueText ()) : " +∞" )
649
+ << (to[keyColumns.size ()].GetDataText () == " 1" ? " ]" : " )" );
761
650
762
- readInfo.ScanBy .push_back (rangeDesc);
763
- op.Properties [" ReadRanges" ].AppendValue (rangeDesc);
764
- }
651
+ readInfo.ScanBy .push_back (rangeDesc);
652
+ op.Properties [" ReadRanges" ].AppendValue (rangeDesc);
765
653
}
766
- } else {
767
- op.Properties [" ReadRanges" ] = rangesDesc;
768
654
}
769
655
} else {
770
- Y_ENSURE ( false , rangesDesc) ;
656
+ op. Properties [ " ReadRanges " ] = rangesDesc;
771
657
}
658
+ } else {
659
+ Y_ENSURE (false , rangesDesc);
660
+ }
772
661
773
- if (!explainPrompt.UsedKeyColumns .empty ()) {
774
- auto & usedColumns = op.Properties [" ReadRangesKeys" ];
775
- for (const auto & col : explainPrompt.UsedKeyColumns ) {
776
- usedColumns.AppendValue (col);
777
- }
662
+ if (!explainPrompt.UsedKeyColumns .empty ()) {
663
+ auto & usedColumns = op.Properties [" ReadRangesKeys" ];
664
+ for (const auto & col : explainPrompt.UsedKeyColumns ) {
665
+ usedColumns.AppendValue (col);
778
666
}
667
+ }
779
668
780
- if (explainPrompt.ExpectedMaxRanges ) {
781
- op.Properties [" ReadRangesExpectedSize" ] = ToString (*explainPrompt.ExpectedMaxRanges );
782
- }
669
+ if (explainPrompt.ExpectedMaxRanges ) {
670
+ op.Properties [" ReadRangesExpectedSize" ] = ToString (*explainPrompt.ExpectedMaxRanges );
671
+ }
783
672
784
- op.Properties [" ReadRangesPointPrefixLen" ] = ToString (explainPrompt.PointPrefixLen );
673
+ op.Properties [" ReadRangesPointPrefixLen" ] = ToString (explainPrompt.PointPrefixLen );
785
674
786
- auto & columns = op.Properties [" ReadColumns" ];
787
- for (const auto & col : sourceSettings.Columns ()) {
788
- readInfo.Columns .emplace_back (TString (col.Value ()));
789
- columns.AppendValue (col.Value ());
790
- }
675
+ auto & columns = op.Properties [" ReadColumns" ];
676
+ for (const auto & col : sourceSettings.Columns ()) {
677
+ readInfo.Columns .emplace_back (TString (col.Value ()));
678
+ columns.AppendValue (col.Value ());
679
+ }
791
680
792
- AddReadTableSettings (op, sourceSettings.Settings (), readInfo);
681
+ AddReadTableSettings (op, sourceSettings.Settings (), readInfo);
793
682
794
- AddOptimizerEstimates (op, sourceSettings);
683
+ AddOptimizerEstimates (op, sourceSettings);
795
684
796
- auto readName = GetNameByReadType (readInfo.Type );
797
- op.Properties [" Name" ] = readName;
798
- AddOperator (planNode, readName, std::move (op));
685
+ auto readName = GetNameByReadType (readInfo.Type );
686
+ op.Properties [" Name" ] = readName;
687
+ AddOperator (planNode, readName, std::move (op));
799
688
800
- SerializerCtx.Tables [table].Reads .push_back (std::move (readInfo));
801
- }
689
+ SerializerCtx.Tables [table].Reads .push_back (std::move (readInfo));
802
690
}
803
691
804
692
// Try get cluster from data surce or data sink node
@@ -1015,7 +903,9 @@ class TxPlanSerializer {
1015
903
TMaybe<std::variant<ui32, TArgContext>> operatorId;
1016
904
1017
905
if (auto maybeRead = TMaybeNode<TKqlReadTableBase>(node)) {
1018
- operatorId = Visit (maybeRead.Cast (), planNode);
906
+ auto read = maybeRead.Cast ();
907
+ TString table = TString (read .Table ().Path ()); TKqlKeyRange range = read .Range ();
908
+ operatorId = Visit (table, range, read , planNode);
1019
909
} else if (TMaybeNode<TKqlReadTableRangesBase>(node) && !TMaybeNode<TKqpReadOlapTableRangesBase>(node)) {
1020
910
auto maybeReadRanges = TMaybeNode<TKqlReadTableRangesBase>(node);
1021
911
operatorId = Visit (maybeReadRanges.Cast (), planNode);
@@ -1742,45 +1632,41 @@ class TxPlanSerializer {
1742
1632
return operatorId;
1743
1633
}
1744
1634
1745
- std::variant<ui32, TArgContext> Visit (const TKqlReadTableBase& read, TQueryPlanNode& planNode) {
1746
- auto table = TString (read .Table ().Path ());
1747
- auto range = read .Range ();
1748
-
1635
+ template <typename TReadTableNode>
1636
+ std::variant<ui32, TArgContext> Visit (const TString& table, const TKqlKeyRange& range, const TReadTableNode& read, TQueryPlanNode& planNode) {
1749
1637
TOperator op;
1750
1638
TTableRead readInfo;
1751
1639
1752
1640
auto describeBoundary = [this ](const TExprBase& key) {
1753
- if (auto param = key.Maybe <TCoParameter>()) {
1754
- return param.Cast ().Name ().StringValue ();
1755
- }
1641
+ TString res (" n/a" );
1756
1642
1757
- if (auto param = key.Maybe <TCoNth>().Tuple ().Maybe <TCoParameter>()) {
1643
+ if (auto param = key.Maybe <TCoParameter>()) {
1644
+ res = param.Cast ().Name ().StringValue ();
1645
+ } else if (auto param = key.Maybe <TCoNth>().Tuple ().Maybe <TCoParameter>()) {
1758
1646
if (auto maybeResultBinding = ContainResultBinding (param.Cast ().Name ().StringValue ())) {
1759
1647
auto [txId, resId] = *maybeResultBinding;
1760
1648
if (auto result = GetResult (txId, resId)) {
1761
1649
auto index = FromString<ui32>(key.Cast <TCoNth>().Index ());
1762
1650
Y_ENSURE (index < result->Size ());
1763
- return DescribeValue ((*result)[index ]);
1651
+ res = DescribeValue ((*result)[index ]);
1764
1652
}
1765
1653
}
1654
+ } else if (auto literal = key.Maybe <TCoUuid>()) {
1655
+ res = NUuid::UuidBytesToString (literal.Cast ().Literal ().StringValue ());
1656
+ } else if (auto literal = key.Maybe <TCoDataCtor>()) {
1657
+ res = literal.Cast ().Literal ().StringValue ();
1658
+ } else if (auto literal = key.Maybe <TCoNothing>()) {
1659
+ res = TString (" null" );
1766
1660
}
1767
1661
1768
- if (auto literal = key.Maybe <TCoDataCtor>()) {
1769
- return literal.Cast ().Literal ().StringValue ();
1770
- }
1771
-
1772
- if (auto literal = key.Maybe <TCoNothing>()) {
1773
- return TString (" null" );
1774
- }
1775
-
1776
- return TString (" n/a" );
1662
+ return res.empty ()? " «»" : res;
1777
1663
};
1778
1664
1779
1665
/* Collect info about scan range */
1780
1666
struct TKeyPartRange {
1781
- TString From;
1782
- TString To;
1783
- TString ColumnName;
1667
+ std::optional<std::string> From{} ;
1668
+ std::optional<std::string> To{} ;
1669
+ std::string ColumnName{} ;
1784
1670
};
1785
1671
auto & tableData = SerializerCtx.TablesData ->GetTable (SerializerCtx.Cluster , table);
1786
1672
op.Properties [" Table" ] = tableData.RelativePath ? *tableData.RelativePath : table;
@@ -1811,20 +1697,20 @@ class TxPlanSerializer {
1811
1697
TStringBuilder rangeDescr;
1812
1698
1813
1699
if (keyPartRange.From == keyPartRange.To ) {
1814
- if (keyPartRange.From .Empty ()) {
1700
+ if (! keyPartRange.From .has_value ()) {
1815
1701
rangeDescr << keyPartRange.ColumnName << " (-∞, +∞)" ;
1816
1702
readInfo.ScanBy .push_back (rangeDescr);
1817
1703
} else {
1818
1704
rangeDescr << keyPartRange.ColumnName
1819
- << " (" << RemoveForbiddenChars (keyPartRange.From ) << " )" ;
1705
+ << " (" << RemoveForbiddenChars (* keyPartRange.From ) << " )" ;
1820
1706
readInfo.LookupBy .push_back (rangeDescr);
1821
1707
}
1822
1708
} else {
1823
1709
rangeDescr << keyPartRange.ColumnName << " "
1824
- << (keyPartRange.From .Empty () ? " (" : leftParen)
1825
- << (keyPartRange.From .Empty () ? " -∞" : RemoveForbiddenChars (keyPartRange.From )) << " , "
1826
- << (keyPartRange.To .Empty () ? " +∞" : RemoveForbiddenChars (keyPartRange.To ))
1827
- << (keyPartRange.To .Empty () ? " )" : rightParen);
1710
+ << (! keyPartRange.From .has_value () ? " (" : leftParen)
1711
+ << (! keyPartRange.From .has_value () ? " -∞" : RemoveForbiddenChars (* keyPartRange.From )) << " , "
1712
+ << (! keyPartRange.To .has_value () ? " +∞" : RemoveForbiddenChars (* keyPartRange.To ))
1713
+ << (! keyPartRange.To .has_value () ? " )" : rightParen);
1828
1714
readInfo.ScanBy .push_back (rangeDescr);
1829
1715
hasRangeScans = true ;
1830
1716
}
@@ -1846,7 +1732,11 @@ class TxPlanSerializer {
1846
1732
columns.AppendValue (col.Value ());
1847
1733
}
1848
1734
1849
- AddReadTableSettings (op, read , readInfo);
1735
+ if constexpr (std::is_same_v<TKqpReadRangesSourceSettings, TReadTableNode>) {
1736
+ AddReadTableSettings (op, read .Settings (), readInfo);
1737
+ } else {
1738
+ AddReadTableSettings (op, read , readInfo);
1739
+ }
1850
1740
1851
1741
SerializerCtx.Tables [table].Reads .push_back (readInfo);
1852
1742
0 commit comments