Skip to content

Commit a360688

Browse files
committed
KIKIMR-19719: Lookup for simple PgSelect
1 parent 19d7298 commit a360688

File tree

7 files changed

+168
-14
lines changed

7 files changed

+168
-14
lines changed

ydb/core/kqp/opt/kqp_query_plan.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -707,8 +707,8 @@ class TxPlanSerializer {
707707
TStringBuilder rangeDesc;
708708
rangeDesc << keyColumns[colId] << " "
709709
<< (from[keyColumns.size()].GetDataText() == "1" ? "[" : "(")
710-
<< (from[colId].HaveValue() ? from[colId].GetDataText() : "-∞") << ", "
711-
<< (to[colId].HaveValue() ? to[colId].GetDataText() : "+∞")
710+
<< (from[colId].HaveValue() ? from[colId].GetSimpleValueText() : "-∞") << ", "
711+
<< (to[colId].HaveValue() ? to[colId].GetSimpleValueText() : "+∞")
712712
<< (to[keyColumns.size()].GetDataText() == "1" ? "]" : ")");
713713

714714
readInfo.ScanBy.push_back(rangeDesc);
@@ -1469,8 +1469,8 @@ class TxPlanSerializer {
14691469
TStringBuilder rangeDesc;
14701470
rangeDesc << keyColumns[colId] << " "
14711471
<< (from[keyColumns.size()].GetDataText() == "1" ? "[" : "(")
1472-
<< (from[colId].HaveValue() ? from[colId].GetDataText() : "-∞") << ", "
1473-
<< (to[colId].HaveValue() ? to[colId].GetDataText() : "+∞")
1472+
<< (from[colId].HaveValue() ? from[colId].GetSimpleValueText() : "-∞") << ", "
1473+
<< (to[colId].HaveValue() ? to[colId].GetSimpleValueText() : "+∞")
14741474
<< (to[keyColumns.size()].GetDataText() == "1" ? "]" : ")");
14751475

14761476
readInfo.ScanBy.push_back(rangeDesc);

ydb/core/kqp/opt/logical/kqp_opt_log.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ class TKqpLogicalOptTransformer : public TOptimizeTransformerBase {
2828
, Config(config)
2929
{
3030
#define HNDL(name) "KqpLogical-"#name, Hndl(&TKqpLogicalOptTransformer::name)
31-
AddHandler(0, &TCoFlatMap::Match, HNDL(PushPredicateToReadTable));
32-
AddHandler(0, &TCoFlatMap::Match, HNDL(PushExtractedPredicateToReadTable));
31+
AddHandler(0, &TCoFlatMapBase::Match, HNDL(PushPredicateToReadTable));
32+
AddHandler(0, &TCoFlatMapBase::Match, HNDL(PushExtractedPredicateToReadTable));
3333
AddHandler(0, &TCoAggregate::Match, HNDL(RewriteAggregate));
3434
AddHandler(0, &TCoAggregateCombine::Match, HNDL(PushdownOlapGroupByKeys));
3535
AddHandler(0, &TCoTake::Match, HNDL(RewriteTakeSortToTopSort));

ydb/core/kqp/opt/logical/kqp_opt_log_ranges_predext.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ TMaybeNode<TExprBase> TryBuildTrivialReadTable(TCoFlatMap& flatmap, TKqlReadTabl
181181
TExprBase KqpPushExtractedPredicateToReadTable(TExprBase node, TExprContext& ctx, const TKqpOptimizeContext& kqpCtx,
182182
TTypeAnnotationContext& typesCtx)
183183
{
184-
if (!node.Maybe<TCoFlatMap>()) {
184+
if (!node.Maybe<TCoFlatMapBase>()) {
185185
return node;
186186
}
187187

188-
auto flatmap = node.Cast<TCoFlatMap>();
188+
auto flatmap = node.Cast<TCoFlatMapBase>();
189189

190190
if (!IsPredicateFlatMap(flatmap.Lambda().Body().Ref())) {
191191
return node;
@@ -252,6 +252,8 @@ TExprBase KqpPushExtractedPredicateToReadTable(TExprBase node, TExprContext& ctx
252252
kqpCtx.Cluster,
253253
mainTableDesc.Metadata->GetIndexMetadata(TString(indexName.Cast())).first->Name)
254254
: mainTableDesc;
255+
YQL_ENSURE(node.Maybe<TCoFlatMap>(), "got OrderedFlatMap with disabled PredicateExtract20");
256+
auto flatmap = node.Cast<TCoFlatMap>();
255257
if (auto expr = TryBuildTrivialReadTable(flatmap, read, *readMatch, tableDesc, ctx, kqpCtx, indexName)) {
256258
return expr.Cast();
257259
}
@@ -501,10 +503,17 @@ TExprBase KqpPushExtractedPredicateToReadTable(TExprBase node, TExprContext& ctx
501503

502504
*input = readMatch->BuildProcessNodes(*input, ctx);
503505

504-
return Build<TCoFlatMap>(ctx, node.Pos())
505-
.Input(*input)
506-
.Lambda(residualLambda)
507-
.Done();
506+
if (node.Maybe<TCoFlatMap>()) {
507+
return Build<TCoFlatMap>(ctx, node.Pos())
508+
.Input(*input)
509+
.Lambda(residualLambda)
510+
.Done();
511+
} else {
512+
return Build<TCoOrderedFlatMap>(ctx, node.Pos())
513+
.Input(*input)
514+
.Lambda(residualLambda)
515+
.Done();
516+
}
508517
}
509518

510519
} // namespace NKikimr::NKqp::NOpt

ydb/core/kqp/opt/query_plan_value/kqp_query_plan_value.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,15 @@ TString TValue::GetPgText() const {
1818
return convertResult.Str;
1919
}
2020

21+
TString TValue::GetSimpleValueText() const {
22+
if (Type.GetKind() == NKikimrMiniKQL::ETypeKind::Pg) {
23+
return GetPgText();
24+
}
25+
if (Type.GetKind() == NKikimrMiniKQL::ETypeKind::Data) {
26+
return GetDataText();
27+
}
28+
Y_ENSURE(false, TStringBuilder() << "unexpected NKikimrMiniKQL::ETypeKind: " << ETypeKind_Name(GetType().GetKind()));
29+
}
30+
2131
}
2232
}

ydb/core/kqp/ut/pg/kqp_pg_ut.cpp

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3529,7 +3529,8 @@ Y_UNIT_TEST_SUITE(KqpPg) {
35293529
SELECT * FROM PgTable WHERE key = 'a';
35303530
)");
35313531
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::BeginTx().CommitTx(), settings).ExtractValueSync();
3532-
UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
3532+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::PRECONDITION_FAILED, result.GetIssues().ToString());
3533+
UNIT_ASSERT(result.GetIssues().ToString().Contains("invalid input syntax for type integer: \"a\""));
35333534
}
35343535
}
35353536

@@ -3608,6 +3609,127 @@ Y_UNIT_TEST_SUITE(KqpPg) {
36083609
UNIT_ASSERT(result.GetIssues().ToString().Contains("invalid byte sequence for encoding \"UTF8\": 0x00"));
36093610
}
36103611
}
3612+
3613+
Y_UNIT_TEST(NoSelectFullScan) {
3614+
NKikimrConfig::TAppConfig appConfig;
3615+
appConfig.MutableTableServiceConfig()->SetEnablePreparedDdl(true);
3616+
auto setting = NKikimrKqp::TKqpSetting();
3617+
auto serverSettings = TKikimrSettings()
3618+
.SetAppConfig(appConfig)
3619+
.SetKqpSettings({setting});
3620+
TKikimrRunner kikimr(serverSettings.SetWithSampleTables(false));
3621+
auto db = kikimr.GetQueryClient();
3622+
auto settings = NYdb::NQuery::TExecuteQuerySettings().Syntax(NYdb::NQuery::ESyntax::Pg);
3623+
{
3624+
auto result = db.ExecuteQuery(R"(
3625+
CREATE TABLE pgbench_accounts(aid int not null,bid int,abalance int,filler char(84), primary key (aid))
3626+
)", NYdb::NQuery::TTxControl::NoTx(), settings).ExtractValueSync();
3627+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
3628+
}
3629+
{
3630+
auto result = db.ExecuteQuery(R"(
3631+
INSERT INTO pgbench_accounts (aid, bid, abalance, filler) VALUES
3632+
(1, 1, 10, ' '::char),
3633+
(2, 1, 20, ' '::char),
3634+
(3, 1, 30, ' '::char),
3635+
(4, 1, 40, '
3636+
'::char),
3637+
(5, 1, 50, ' '::char),
3638+
(6, 1, 60, ' '::char),
3639+
(7, 1, 70, ' '::char),
3640+
(8, 1, 80, ' '::char),
3641+
(9, 1, 90, ' '::char),
3642+
(10, 1, 100, ' '::char)
3643+
)", NYdb::NQuery::TTxControl::BeginTx().CommitTx(), settings).ExtractValueSync();
3644+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
3645+
}
3646+
{
3647+
auto tc = kikimr.GetTableClient();
3648+
TStreamExecScanQuerySettings settings;
3649+
settings.Explain(true);
3650+
auto it = tc.StreamExecuteScanQuery(R"(
3651+
--!syntax_pg
3652+
SELECT abalance FROM pgbench_accounts WHERE aid = 7 OR aid = 3 ORDER BY abalance;
3653+
)", settings).GetValueSync();
3654+
3655+
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
3656+
3657+
auto res = CollectStreamResult(it);
3658+
UNIT_ASSERT(res.PlanJson);
3659+
3660+
NJson::TJsonValue plan;
3661+
NJson::ReadJsonTree(*res.PlanJson, &plan, true);
3662+
UNIT_ASSERT(ValidatePlanNodeIds(plan));
3663+
3664+
auto fullScan = FindPlanNodeByKv(plan, "Node Type", "Filter-TableFullScan");
3665+
UNIT_ASSERT_C(!fullScan.IsDefined(), "got fullscan, expected lookup");
3666+
auto lookup = FindPlanNodeByKv(plan, "Node Type", "TableLookup");
3667+
UNIT_ASSERT_C(lookup.IsDefined(), "no Table Lookup in plan");
3668+
}
3669+
{
3670+
auto result = db.ExecuteQuery(R"(
3671+
SELECT abalance FROM pgbench_accounts WHERE aid = 7 OR aid = 3 ORDER BY abalance;
3672+
)", NYdb::NQuery::TTxControl::BeginTx().CommitTx(), settings).ExtractValueSync();
3673+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
3674+
CompareYson(R"([
3675+
["30"];["70"]
3676+
])", FormatResultSetYson(result.GetResultSet(0)));
3677+
}
3678+
{
3679+
auto tc = kikimr.GetTableClient();
3680+
TStreamExecScanQuerySettings settings;
3681+
settings.Explain(true);
3682+
auto it = tc.StreamExecuteScanQuery(R"(
3683+
--!syntax_pg
3684+
SELECT abalance FROM pgbench_accounts WHERE aid = 7 OR aid < 3 ORDER BY abalance;
3685+
)", settings).GetValueSync();
3686+
3687+
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
3688+
3689+
auto res = CollectStreamResult(it);
3690+
UNIT_ASSERT(res.PlanJson);
3691+
Cerr << res.PlanJson << Endl;
3692+
3693+
NJson::TJsonValue plan;
3694+
NJson::ReadJsonTree(*res.PlanJson, &plan, true);
3695+
UNIT_ASSERT(ValidatePlanNodeIds(plan));
3696+
3697+
auto fullScan = FindPlanNodeByKv(plan, "Node Type", "Filter-TableFullScan");
3698+
UNIT_ASSERT_C(!fullScan.IsDefined(), "got fullscan, expected lookup");
3699+
auto lookup = FindPlanNodeByKv(plan, "Node Type", "TableRangeScan");
3700+
UNIT_ASSERT_C(lookup.IsDefined(), "no Table Range Scan in plan");
3701+
}
3702+
{
3703+
auto tc = kikimr.GetTableClient();
3704+
TStreamExecScanQuerySettings settings;
3705+
settings.Explain(true);
3706+
auto it = tc.StreamExecuteScanQuery(R"(
3707+
--!syntax_pg
3708+
SELECT abalance FROM pgbench_accounts WHERE aid > 4 AND aid < 3;
3709+
)", settings).GetValueSync();
3710+
3711+
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
3712+
3713+
auto res = CollectStreamResult(it);
3714+
UNIT_ASSERT(res.PlanJson);
3715+
Cerr << res.PlanJson << Endl;
3716+
NJson::TJsonValue plan;
3717+
NJson::ReadJsonTree(*res.PlanJson, &plan, true);
3718+
UNIT_ASSERT(ValidatePlanNodeIds(plan));
3719+
3720+
auto fullScan = FindPlanNodeByKv(plan, "Node Type", "Filter-TableFullScan");
3721+
UNIT_ASSERT_C(!fullScan.IsDefined(), "got fullscan, expected lookup");
3722+
auto lookup = FindPlanNodeByKv(plan, "Node Type", "TableRangeScan");
3723+
UNIT_ASSERT_C(lookup.IsDefined(), "no Table Range Scan in plan");
3724+
}
3725+
{
3726+
auto result = db.ExecuteQuery(R"(
3727+
SELECT abalance FROM pgbench_accounts WHERE aid > 4 AND aid < 3;
3728+
)", NYdb::NQuery::TTxControl::BeginTx().CommitTx(), settings).ExtractValueSync();
3729+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
3730+
CompareYson(R"([])", FormatResultSetYson(result.GetResultSet(0)));
3731+
}
3732+
}
36113733
}
36123734

36133735
} // namespace NKqp

ydb/library/yql/utils/plan/plan_utils.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ TString ToStr(const TCoDataCtor& data) {
2727
return out.Str();
2828
}
2929

30+
TString ToStr(const TCoPgConst& data) {
31+
TStringStream out;
32+
EscapeArbitraryAtom(data.Value().Value(), '"', &out);
33+
return out.Str();
34+
}
35+
36+
3037
TString ToStr(const TCoLambda& lambda) {
3138
return PrettyExprStr(lambda.Body());
3239
}
@@ -143,6 +150,8 @@ TString PrettyExprStr(const TExprBase& expr) {
143150
return TString(expr.Ref().Child(0)->Content());
144151
} else if (auto data = expr.Maybe<TCoDataCtor>()) {
145152
return ToStr(data.Cast());
153+
} else if (auto pgConst = expr.Maybe<TCoPgConst>()) {
154+
return ToStr(pgConst.Cast());
146155
} else if (auto lambda = expr.Maybe<TCoLambda>()) {
147156
return ToStr(lambda.Cast());
148157
} else if (auto asStruct = expr.Maybe<TCoAsStruct>()) {

ydb/public/lib/value/value.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,13 @@ class TValue {
8989
NScheme::TTypeId GetDataType() const;
9090
// gets text representation of simple 'Data' types
9191
TString GetDataText() const;
92+
93+
// You need to add ydb/core/kqp/opt/query_plan_value to PEERDIRs in order to use all Pg-related functions
9294
// gets text representation of simple 'Pg' types
93-
// You need to add ydb/core/kqp/opt/query_plan_value to PEERDIRs in order to use this function
9495
TString GetPgText() const;
96+
// gets text representation of simple 'Data' and 'Pg' types
97+
TString GetSimpleValueText() const;
98+
9599
// returns text representation of value's type
96100
template <typename Format> TString GetTypeText(const Format& format = Format()) const;
97101
// returns text representation of value itself

0 commit comments

Comments
 (0)