Skip to content

Commit 5427f7c

Browse files
authored
Add fulltext KQP query tests (#26566)
1 parent 9a36487 commit 5427f7c

File tree

2 files changed

+330
-1
lines changed

2 files changed

+330
-1
lines changed
Lines changed: 328 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,328 @@
1+
#include <ydb/core/kqp/ut/common/kqp_ut_common.h>
2+
3+
4+
namespace NKikimr::NKqp {
5+
6+
using namespace NYdb;
7+
using namespace NYdb::NTable;
8+
9+
Y_UNIT_TEST_SUITE(KqpFulltextIndexes) {
10+
11+
TKikimrRunner Kikimr() {
12+
NKikimrConfig::TFeatureFlags featureFlags;
13+
featureFlags.SetEnableFulltextIndex(true);
14+
auto settings = TKikimrSettings().SetFeatureFlags(featureFlags);
15+
return TKikimrRunner(settings);
16+
}
17+
18+
void CreateTexts(NQuery::TQueryClient& db) {
19+
TString query = R"sql(
20+
CREATE TABLE `/Root/Texts` (
21+
Key Uint64,
22+
Text String,
23+
Data String,
24+
PRIMARY KEY (Key)
25+
);
26+
)sql";
27+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
28+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
29+
}
30+
31+
void UpsertTexts(NQuery::TQueryClient& db) {
32+
TString query = R"sql(
33+
UPSERT INTO `/Root/Texts` (Key, Text, Data) VALUES
34+
(100, "Cats chase small animals.", "cats data"),
35+
(200, "Dogs chase small cats.", "dogs data"),
36+
(300, "Cats love cats.", "cats cats data"),
37+
(400, "Foxes love dogs.", "fox data")
38+
)sql";
39+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
40+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
41+
}
42+
43+
void UpsertRow(NQuery::TQueryClient& db) {
44+
TString query = R"sql(
45+
UPSERT INTO `/Root/Texts` (Key, Text, Data) VALUES
46+
(250, "Dogs are big animals.", "new dogs data")
47+
)sql";
48+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
49+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
50+
}
51+
52+
void AddIndex(NQuery::TQueryClient& db) {
53+
TString query = R"sql(
54+
ALTER TABLE `/Root/Texts` ADD INDEX fulltext_idx
55+
GLOBAL USING fulltext
56+
ON (Text)
57+
WITH (layout=flat, tokenizer=standard, use_filter_lowercase=true)
58+
)sql";
59+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
60+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
61+
}
62+
63+
void AddIndexCovered(NQuery::TQueryClient& db) {
64+
TString query = R"sql(
65+
ALTER TABLE `/Root/Texts` ADD INDEX fulltext_idx
66+
GLOBAL USING fulltext
67+
ON (Text) COVER (Data)
68+
WITH (layout=flat, tokenizer=standard, use_filter_lowercase=true)
69+
)sql";
70+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
71+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
72+
}
73+
74+
TResultSet ReadIndex(NQuery::TQueryClient& db) {
75+
TString query = R"sql(
76+
SELECT * FROM `/Root/Texts/fulltext_idx/indexImplTable`;
77+
)sql";
78+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
79+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
80+
return result.GetResultSet(0);
81+
}
82+
83+
Y_UNIT_TEST(AddIndex) {
84+
auto kikimr = Kikimr();
85+
auto db = kikimr.GetQueryClient();
86+
87+
CreateTexts(db);
88+
UpsertTexts(db);
89+
AddIndex(db);
90+
91+
auto index = ReadIndex(db);
92+
CompareYson(R"([
93+
[[100u];"animals"];
94+
[[100u];"cats"];
95+
[[200u];"cats"];
96+
[[300u];"cats"];
97+
[[100u];"chase"];
98+
[[200u];"chase"];
99+
[[200u];"dogs"];
100+
[[400u];"dogs"];
101+
[[400u];"foxes"];
102+
[[300u];"love"];
103+
[[400u];"love"];
104+
[[100u];"small"];
105+
[[200u];"small"]
106+
])", NYdb::FormatResultSetYson(index));
107+
}
108+
109+
Y_UNIT_TEST(AddIndexCovered) {
110+
auto kikimr = Kikimr();
111+
auto db = kikimr.GetQueryClient();
112+
113+
CreateTexts(db);
114+
UpsertTexts(db);
115+
AddIndexCovered(db);
116+
117+
auto index = ReadIndex(db);
118+
CompareYson(R"([
119+
[["cats data"];[100u];"animals"];
120+
[["cats data"];[100u];"cats"];
121+
[["dogs data"];[200u];"cats"];
122+
[["cats cats data"];[300u];"cats"];
123+
[["cats data"];[100u];"chase"];
124+
[["dogs data"];[200u];"chase"];
125+
[["dogs data"];[200u];"dogs"];
126+
[["fox data"];[400u];"dogs"];
127+
[["fox data"];[400u];"foxes"];
128+
[["cats cats data"];[300u];"love"];
129+
[["fox data"];[400u];"love"];
130+
[["cats data"];[100u];"small"];
131+
[["dogs data"];[200u];"small"]
132+
])", NYdb::FormatResultSetYson(index));
133+
}
134+
135+
Y_UNIT_TEST(UpsertRow) {
136+
auto kikimr = Kikimr();
137+
auto db = kikimr.GetQueryClient();
138+
139+
CreateTexts(db);
140+
UpsertTexts(db);
141+
AddIndex(db);
142+
return; // TODO: upserts are not implemented
143+
UpsertRow(db);
144+
145+
auto index = ReadIndex(db);
146+
CompareYson(R"([
147+
148+
])", NYdb::FormatResultSetYson(index));
149+
}
150+
151+
Y_UNIT_TEST(UpsertRowCovered) {
152+
auto kikimr = Kikimr();
153+
auto db = kikimr.GetQueryClient();
154+
155+
CreateTexts(db);
156+
UpsertTexts(db);
157+
AddIndexCovered(db);
158+
return; // TODO: upserts are not implemented
159+
UpsertRow(db);
160+
161+
auto index = ReadIndex(db);
162+
CompareYson(R"([
163+
164+
])", NYdb::FormatResultSetYson(index));
165+
}
166+
167+
Y_UNIT_TEST(InsertRow) {
168+
// TODO: inserts are not implemented
169+
}
170+
171+
Y_UNIT_TEST(InsertRowCovered) {
172+
// TODO: inserts are not implemented
173+
}
174+
175+
Y_UNIT_TEST(DeleteRow) {
176+
// TODO: deletes are not implemented
177+
178+
// TODO: test delete by key and filter
179+
}
180+
181+
Y_UNIT_TEST(DeleteRowCovered) {
182+
// TODO: deletes are not implemented
183+
184+
// TODO: test delete by key and filter
185+
}
186+
187+
Y_UNIT_TEST(UpdateRow) {
188+
// TODO: deletes are not implemented
189+
190+
// TODO: test update of key, text, data
191+
}
192+
193+
Y_UNIT_TEST(UpdateRowCovered) {
194+
// TODO: deletes are not implemented
195+
196+
// TODO: test update of key, text, data
197+
}
198+
199+
Y_UNIT_TEST(CreateTable) {
200+
auto kikimr = Kikimr();
201+
auto db = kikimr.GetQueryClient();
202+
203+
{ // CreateTexts
204+
TString query = R"sql(
205+
CREATE TABLE `/Root/Texts` (
206+
Key Uint64,
207+
Text String,
208+
Data String,
209+
PRIMARY KEY (Key),
210+
INDEX fulltext_idx
211+
GLOBAL USING fulltext
212+
ON (Text)
213+
WITH (layout=flat, tokenizer=standard, use_filter_lowercase=true)
214+
);
215+
)sql";
216+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
217+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
218+
}
219+
return; // TODO: upserts are not implemented
220+
UpsertTexts(db);
221+
222+
auto index = ReadIndex(db);
223+
CompareYson(R"([
224+
[[100u];"animals"];
225+
[[100u];"cats"];
226+
[[200u];"cats"];
227+
[[300u];"cats"];
228+
[[100u];"chase"];
229+
[[200u];"chase"];
230+
[[200u];"dogs"];
231+
[[400u];"dogs"];
232+
[[400u];"foxes"];
233+
[[300u];"love"];
234+
[[400u];"love"];
235+
[[100u];"small"];
236+
[[200u];"small"]
237+
])", NYdb::FormatResultSetYson(index));
238+
}
239+
240+
Y_UNIT_TEST(CreateTableCovered) {
241+
auto kikimr = Kikimr();
242+
auto db = kikimr.GetQueryClient();
243+
244+
{ // CreateTexts
245+
TString query = R"sql(
246+
CREATE TABLE `/Root/Texts` (
247+
Key Uint64,
248+
Text String,
249+
Data String,
250+
PRIMARY KEY (Key),
251+
INDEX fulltext_idx
252+
GLOBAL USING fulltext
253+
ON (Text) COVER (Data)
254+
WITH (layout=flat, tokenizer=standard, use_filter_lowercase=true)
255+
);
256+
)sql";
257+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
258+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
259+
}
260+
return; // TODO: upserts are not implemented
261+
UpsertTexts(db);
262+
263+
auto index = ReadIndex(db);
264+
CompareYson(R"([
265+
[["cats data"];[100u];"animals"];
266+
[["cats data"];[100u];"cats"];
267+
[["dogs data"];[200u];"cats"];
268+
[["cats cats data"];[300u];"cats"];
269+
[["cats data"];[100u];"chase"];
270+
[["dogs data"];[200u];"chase"];
271+
[["dogs data"];[200u];"dogs"];
272+
[["fox data"];[400u];"dogs"];
273+
[["fox data"];[400u];"foxes"];
274+
[["cats cats data"];[300u];"love"];
275+
[["fox data"];[400u];"love"];
276+
[["cats data"];[100u];"small"];
277+
[["dogs data"];[200u];"small"]
278+
])", NYdb::FormatResultSetYson(index));
279+
}
280+
281+
Y_UNIT_TEST(NoBulkUpsert) {
282+
auto kikimr = Kikimr();
283+
auto db = kikimr.GetQueryClient();
284+
285+
CreateTexts(db);
286+
AddIndex(db);
287+
288+
{ // BulkUpsert
289+
NYdb::TValueBuilder rows;
290+
rows.BeginList();
291+
rows.AddListItem()
292+
.BeginStruct()
293+
.AddMember("Key").Uint64(900)
294+
.EndStruct();
295+
rows.EndList();
296+
auto result = kikimr.GetTableClient().BulkUpsert("/Root/Texts", rows.Build()).GetValueSync();
297+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SCHEME_ERROR, result.GetIssues().ToString());
298+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Only async-indexed tables are supported by BulkUpsert");
299+
}
300+
301+
auto index = ReadIndex(db);
302+
CompareYson(R"([])", NYdb::FormatResultSetYson(index));
303+
}
304+
305+
Y_UNIT_TEST(NoIndexImplTableUpdates) {
306+
auto kikimr = Kikimr();
307+
auto db = kikimr.GetQueryClient();
308+
309+
CreateTexts(db);
310+
AddIndex(db);
311+
312+
{ // UpsertRow
313+
TString query = R"sql(
314+
UPSERT INTO `/Root/Texts/fulltext_idx/indexImplTable` (__ydb_token, Key) VALUES
315+
("dogs", 901)
316+
)sql";
317+
auto result = db.ExecuteQuery(query, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
318+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::BAD_REQUEST, result.GetIssues().ToString());
319+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Writing to index implementation tables is not allowed");
320+
}
321+
322+
auto index = ReadIndex(db);
323+
CompareYson(R"([])", NYdb::FormatResultSetYson(index));
324+
}
325+
326+
}
327+
328+
}

ydb/core/kqp/ut/indexes/ya.make

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ ELSE()
1111
ENDIF()
1212

1313
SRCS(
14-
kqp_indexes_ut.cpp
14+
kqp_indexes_fulltext_ut.cpp
1515
kqp_indexes_multishard_ut.cpp
1616
kqp_indexes_prefixed_vector_ut.cpp
17+
kqp_indexes_ut.cpp
1718
kqp_indexes_vector_ut.cpp
1819
)
1920

0 commit comments

Comments
 (0)