Skip to content

Commit 476779e

Browse files
authored
Reject programs without projection (#16505) (#17154)
1 parent 9e56c53 commit 476779e

File tree

4 files changed

+136
-1
lines changed

4 files changed

+136
-1
lines changed

ydb/core/kqp/ut/olap/kqp_olap_ut.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,5 +3518,43 @@ Y_UNIT_TEST_SUITE(KqpOlap) {
35183518

35193519
testHelper.ReadData("SELECT a, b FROM `/Root/ColumnTableTest` WHERE b = 2 LIMIT 2", "[[2u;2u]]");
35203520
}
3521+
3522+
Y_UNIT_TEST(SimpleRequestHasProjections) {
3523+
auto settings = TKikimrSettings()
3524+
.SetWithSampleTables(false);
3525+
TKikimrRunner kikimr(settings);
3526+
TLocalHelper(kikimr).CreateTestOlapTable();
3527+
WriteTestData(kikimr, "/Root/olapStore/olapTable", 0, 1000000, 20);
3528+
auto client = kikimr.GetTableClient();
3529+
Tests::NCommon::TLoggerInit(kikimr).Initialize();
3530+
3531+
{
3532+
auto it = client.StreamExecuteScanQuery(R"(
3533+
--!syntax_v1
3534+
3535+
SELECT 1
3536+
FROM `/Root/olapStore/olapTable`
3537+
)").GetValueSync();
3538+
3539+
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
3540+
TString result = StreamResultToYson(it);
3541+
3542+
CompareYson(result, R"([[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1];[1]])");
3543+
}
3544+
3545+
{
3546+
auto it = client.StreamExecuteScanQuery(R"(
3547+
--!syntax_v1
3548+
3549+
SELECT count(*)
3550+
FROM `/Root/olapStore/olapTable`
3551+
)").GetValueSync();
3552+
3553+
UNIT_ASSERT_C(it.IsSuccess(), it.GetIssues().ToString());
3554+
TString result = StreamResultToYson(it);
3555+
3556+
CompareYson(result, R"([[20u]])");
3557+
}
3558+
}
35213559
}
35223560
}

ydb/core/tx/columnshard/test_helper/shard_reader.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class TShardReader {
3535
std::vector<std::shared_ptr<arrow::RecordBatch>> ResultBatches;
3636
YDB_READONLY(ui32, IterationsCount, 0);
3737

38+
std::vector<Ydb::Issue::IssueMessage> Errors;
39+
3840
public:
3941
ui64 GetReadStat(const TString& paramName) const {
4042
AFL_VERIFY(IsCorrectlyFinished());
@@ -92,6 +94,10 @@ class TShardReader {
9294
return IsFinished() && *Finished == -1;
9395
}
9496

97+
const std::vector<Ydb::Issue::IssueMessage>& GetErrors() const {
98+
return Errors;
99+
}
100+
95101
bool InitializeScanner() {
96102
AFL_VERIFY(!ScanActorId);
97103
const TActorId sender = Runtime.AllocateEdgeActor();
@@ -104,6 +110,9 @@ class TShardReader {
104110
ScanActorId = ActorIdFromProto(msg.GetScanActorId());
105111
return true;
106112
} else if (auto* evError = std::get<1>(event)) {
113+
for (auto issue : evError->Record.GetIssues()) {
114+
Errors.emplace_back(issue);
115+
}
107116
Finished = -1;
108117
} else {
109118
AFL_VERIFY(false);
@@ -136,6 +145,9 @@ class TShardReader {
136145
Finished = 1;
137146
}
138147
} else if (auto* evError = std::get<1>(event)) {
148+
for (auto issue : evError->Record.GetIssues()) {
149+
Errors.emplace_back(issue);
150+
}
139151
Finished = -1;
140152
} else {
141153
AFL_VERIFY(false);

ydb/core/tx/columnshard/ut_rw/ut_columnshard_read_write.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,83 @@ void TestSomePrograms(const TestTableDescription& table) {
13541354
}
13551355
}
13561356

1357+
void TestReadWithProgramNoProjection(const TestTableDescription& table = {}) {
1358+
TTestBasicRuntime runtime;
1359+
TTester::Setup(runtime);
1360+
auto csDefaultControllerGuard = NKikimr::NYDBTest::TControllers::RegisterCSControllerGuard<TDefaultTestsController>();
1361+
1362+
TActorId sender = runtime.AllocateEdgeActor();
1363+
CreateTestBootstrapper(runtime, CreateTestTabletInfo(TTestTxConfig::TxTablet0, TTabletTypes::ColumnShard), &CreateColumnShard);
1364+
1365+
TDispatchOptions options;
1366+
options.FinalEvents.push_back(TDispatchOptions::TFinalEventCondition(TEvTablet::EvBoot));
1367+
runtime.DispatchEvents(options);
1368+
1369+
ui64 writeId = 0;
1370+
ui64 tableId = 1;
1371+
ui64 txId = 100;
1372+
1373+
auto planStep = SetupSchema(runtime, sender, tableId, table);
1374+
1375+
{ // write some data
1376+
std::vector<ui64> writeIds;
1377+
bool ok = WriteData(runtime, sender, writeId, tableId, MakeTestBlob({ 0, 100 }, table.Schema), table.Schema, true, &writeIds);
1378+
UNIT_ASSERT(ok);
1379+
planStep = ProposeCommit(runtime, sender, txId, writeIds);
1380+
PlanCommit(runtime, sender, planStep, txId);
1381+
}
1382+
1383+
std::vector<TString> programs;
1384+
programs.push_back("XXXYYYZZZ");
1385+
{
1386+
NKikimrSSA::TProgram ssa = MakeSelect(TAssignment::FUNC_CMP_EQUAL);
1387+
TString serialized;
1388+
UNIT_ASSERT(ssa.SerializeToString(&serialized));
1389+
1390+
NKikimrSSA::TOlapProgram program;
1391+
program.SetProgram(serialized);
1392+
1393+
programs.push_back("");
1394+
UNIT_ASSERT(program.SerializeToString(&programs.back()));
1395+
1396+
//remove projections
1397+
auto* commands = ssa.MutableCommand();
1398+
for(int i = commands->size() - 1; i >= 0; --i) {
1399+
if ((*commands)[i].HasProjection()) {
1400+
commands->DeleteSubrange(i, 1);
1401+
}
1402+
}
1403+
1404+
UNIT_ASSERT(ssa.SerializeToString(&serialized));
1405+
program.SetProgram(serialized);
1406+
programs.push_back("");
1407+
UNIT_ASSERT(program.SerializeToString(&programs.back()));
1408+
}
1409+
1410+
ui32 i = 0;
1411+
for (auto& programText : programs) {
1412+
TShardReader reader(runtime, TTestTxConfig::TxTablet0, tableId, NOlap::TSnapshot(planStep, txId));
1413+
reader.SetProgram(programText);
1414+
auto rb = reader.ReadAll();
1415+
switch(i) {
1416+
case 0:
1417+
UNIT_ASSERT(reader.IsError());
1418+
break;
1419+
1420+
case 1:
1421+
UNIT_ASSERT(!reader.IsError());
1422+
break;
1423+
1424+
case 2:
1425+
UNIT_ASSERT(reader.IsError());
1426+
UNIT_ASSERT(reader.GetErrors().back().Getmessage().Contains("program has no projections"));
1427+
break;
1428+
}
1429+
UNIT_ASSERT(reader.IsFinished());
1430+
++i;
1431+
}
1432+
}
1433+
13571434
struct TReadAggregateResult {
13581435
ui32 NumRows = 1;
13591436

@@ -1920,6 +1997,10 @@ Y_UNIT_TEST_SUITE(TColumnShardTestReadWrite) {
19201997
TestSomePrograms(table);
19211998
}
19221999

2000+
Y_UNIT_TEST(ReadWithProgramNoProjection) {
2001+
TestReadWithProgramNoProjection();
2002+
}
2003+
19232004
Y_UNIT_TEST(ReadAggregate) {
19242005
auto schema = TTestSchema::YdbAllTypesSchema();
19252006
auto testBlob = MakeTestBlob({ 0, 100 }, schema);

ydb/core/tx/program/program.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ TConclusionStatus TProgramContainer::ParseProgram(const NArrow::NSSA::IColumnRes
100100
using TId = NKikimrSSA::TProgram::TCommand;
101101

102102
AFL_DEBUG(NKikimrServices::TX_COLUMNSHARD)("parse_proto_program", program.DebugString());
103-
// Cerr << program.DebugString() << Endl;
104103
NArrow::NSSA::TProgramBuilder programBuilder(columnResolver, KernelsRegistry);
104+
bool hasProjection = false;
105105
for (auto& cmd : program.GetCommand()) {
106106
switch (cmd.GetLineCase()) {
107107
case TId::kAssign: {
@@ -123,6 +123,7 @@ TConclusionStatus TProgramContainer::ParseProgram(const NArrow::NSSA::IColumnRes
123123
if (status.IsFail()) {
124124
return status;
125125
}
126+
hasProjection = true;
126127
break;
127128
}
128129
case TId::kGroupBy: {
@@ -136,6 +137,9 @@ TConclusionStatus TProgramContainer::ParseProgram(const NArrow::NSSA::IColumnRes
136137
return TConclusionStatus::Fail("incorrect SSA line case");
137138
}
138139
}
140+
if (!hasProjection) {
141+
return TConclusionStatus::Fail("program has no projections");
142+
}
139143
auto programStatus = programBuilder.Finish();
140144
if (programStatus.IsFail()) {
141145
return programStatus;

0 commit comments

Comments
 (0)