@@ -187,4 +187,49 @@ TEST_CASE("Test parsing KQL", "[KQL]") {
187
187
auto failure = parse_kql_expression (incorrect_query);
188
188
REQUIRE (nullptr == failure);
189
189
}
190
+
191
+ SECTION (" Escape sequences in column name" ) {
192
+ auto query = GENERATE (
193
+ " a\\ .b.c: *" ,
194
+ " \" a\\ .b.c\" : *" ,
195
+ " a\\ .b: {c: *}" ,
196
+ " \" a\\ .b\" : {\" c\" : *}"
197
+ );
198
+ stringstream escaped_column_query{query};
199
+ auto filter
200
+ = std::dynamic_pointer_cast<FilterExpr>(parse_kql_expression (escaped_column_query));
201
+ REQUIRE (nullptr != filter);
202
+ REQUIRE (nullptr != filter->get_operand ());
203
+ REQUIRE (nullptr != filter->get_column ());
204
+ REQUIRE (false == filter->has_only_expression_operands ());
205
+ REQUIRE (false == filter->is_inverted ());
206
+ REQUIRE (FilterOperation::EQ == filter->get_operation ());
207
+ REQUIRE (2 == filter->get_column ()->get_descriptor_list ().size ());
208
+ auto it = filter->get_column ()->descriptor_begin ();
209
+ REQUIRE (DescriptorToken{" a.b" } == *it++);
210
+ REQUIRE (DescriptorToken{" c" } == *it++);
211
+ }
212
+
213
+ SECTION (" Illegal escape sequences in column name" ) {
214
+ auto query = GENERATE (
215
+ // "a\\:*", this case is technically legal since ':' gets escaped
216
+ " \" a\\\" :*" ,
217
+ " a\\ :*" ,
218
+ " \" a\\\" :*" ,
219
+ " a.:*" ,
220
+ " \" a.\" :*" ,
221
+ " a. :*" ,
222
+ " \" a.\" :*"
223
+ );
224
+ stringstream illegal_escape{query};
225
+ auto filter = parse_kql_expression (illegal_escape);
226
+ REQUIRE (nullptr == filter);
227
+ }
228
+
229
+ SECTION (" Empty token in column name" ) {
230
+ auto query = GENERATE (" .a:*" , " a.:*" , " a..c:*" , " a.b.:*" );
231
+ stringstream empty_token_column{query};
232
+ auto filter = parse_kql_expression (empty_token_column);
233
+ REQUIRE (nullptr == filter);
234
+ }
190
235
}
0 commit comments