Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(search_family): Add option tests for the FT.CREATE command #4678

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions src/server/search/search_family.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ ParseResult<bool> ParseStopwords(CmdArgParser* parser, DocIndex* index) {
ParseResult<bool> ParseSchema(CmdArgParser* parser, DocIndex* index) {
auto& schema = index->schema;

if (!parser->HasNext()) {
return CreateSyntaxError("Fields arguments are missing"sv);
}

while (parser->HasNext()) {
string_view field = parser->Next();
string_view field_alias = field;
Expand All @@ -204,10 +208,20 @@ ParseResult<bool> ParseSchema(CmdArgParser* parser, DocIndex* index) {
// AS [alias]
parser->Check("AS", &field_alias);

if (schema.field_names.contains(field_alias)) {
return CreateSyntaxError(absl::StrCat("Duplicate field in schema - "sv, field_alias));
}

// Determine type
using search::SchemaField;
auto parsed_params = parser->MapNext("TAG"sv, &ParseTag, "TEXT"sv, &ParseText, "NUMERIC"sv,
&ParseNumeric, "VECTOR"sv, &ParseVector)(parser);
auto params_parser = parser->TryMapNext("TAG"sv, &ParseTag, "TEXT"sv, &ParseText, "NUMERIC"sv,
&ParseNumeric, "VECTOR"sv, &ParseVector);
if (!params_parser) {
return CreateSyntaxError(
absl::StrCat("Field type "sv, parser->Next(), " is not supported"sv));
}

auto parsed_params = params_parser.value()(parser);
if (!parsed_params) {
return make_unexpected(parsed_params.error());
}
Expand All @@ -231,12 +245,9 @@ ParseResult<bool> ParseSchema(CmdArgParser* parser, DocIndex* index) {
parser->Skip(2);

schema.fields[field] = {field_type, flags, string{field_alias}, params};
schema.field_names[field_alias] = field;
}

// Build field name mapping table
for (const auto& [field_ident, field_info] : schema.fields)
schema.field_names[field_info.short_name] = field_ident;

return false;
}

Expand Down
31 changes: 31 additions & 0 deletions src/server/search/search_family_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1983,4 +1983,35 @@ TEST_F(SearchFamilyTest, InvalidAggregateOptions) {
EXPECT_THAT(resp, ErrArg(kInvalidIntErr));
}

TEST_F(SearchFamilyTest, InvalidCreateOptions) {
// Test with a duplicate field in the schema
auto resp = Run({"FT.CREATE", "index", "ON", "HASH", "SCHEMA", "title", "TEXT", "title", "TEXT"});
EXPECT_THAT(resp, ErrArg("Duplicate field in schema - title"));

// Test with no fields in the schema
resp = Run({"FT.CREATE", "index", "ON", "HASH", "SCHEMA"});
EXPECT_THAT(resp, ErrArg("Fields arguments are missing"));

// Test with an invalid field type
resp = Run({"FT.CREATE", "index", "ON", "HASH", "SCHEMA", "title", "UNKNOWN_TYPE"});
EXPECT_THAT(resp, ErrArg("Field type UNKNOWN_TYPE is not supported"));

// Test with an invalid STOPWORDS argument
resp = Run({"FT.CREATE", "index", "ON", "HASH", "STOPWORDS", "10", "the", "and", "of", "SCHEMA",
"title", "TEXT"});
EXPECT_THAT(resp, ErrArg(kSyntaxErr));

resp = Run({"FT.CREATE", "index", "ON", "HASH", "STOPWORDS", "99999999999999999999", "the", "and",
"of", "SCHEMA", "title", "TEXT"});
EXPECT_THAT(resp, ErrArg(kInvalidIntErr));

resp = Run({"FT.CREATE", "index", "ON", "HASH", "STOPWORDS", "-1", "the", "and", "of", "SCHEMA",
"title", "TEXT"});
EXPECT_THAT(resp, ErrArg(kInvalidIntErr));

resp = Run({"FT.CREATE", "index", "ON", "HASH", "STOPWORDS", "not_a_number", "the", "and", "of",
"SCHEMA", "title", "TEXT"});
EXPECT_THAT(resp, ErrArg(kInvalidIntErr));
}

} // namespace dfly
Loading