Make EQL case sensitive by default and adapt some of the string functions Remove the case sensitive option from Between string function Add case_insensitive option to term and wildcard queries usage (cherry picked from commit 7550e0664c8c2f1f13519036c759b1e76345551f)
This commit is contained in:
parent
1a6837883a
commit
76bba601ab
|
@ -39,7 +39,6 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
private QueryBuilder filter = null;
|
private QueryBuilder filter = null;
|
||||||
private String timestampField = "@timestamp";
|
private String timestampField = "@timestamp";
|
||||||
private String eventCategoryField = "event.category";
|
private String eventCategoryField = "event.category";
|
||||||
private boolean isCaseSensitive = true;
|
|
||||||
|
|
||||||
private int size = 10;
|
private int size = 10;
|
||||||
private int fetchSize = 1000;
|
private int fetchSize = 1000;
|
||||||
|
@ -55,7 +54,6 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
static final String KEY_TIMESTAMP_FIELD = "timestamp_field";
|
static final String KEY_TIMESTAMP_FIELD = "timestamp_field";
|
||||||
static final String KEY_TIEBREAKER_FIELD = "tiebreaker_field";
|
static final String KEY_TIEBREAKER_FIELD = "tiebreaker_field";
|
||||||
static final String KEY_EVENT_CATEGORY_FIELD = "event_category_field";
|
static final String KEY_EVENT_CATEGORY_FIELD = "event_category_field";
|
||||||
static final String KEY_CASE_SENSITIVE = "case_sensitive";
|
|
||||||
static final String KEY_SIZE = "size";
|
static final String KEY_SIZE = "size";
|
||||||
static final String KEY_FETCH_SIZE = "fetch_size";
|
static final String KEY_FETCH_SIZE = "fetch_size";
|
||||||
static final String KEY_QUERY = "query";
|
static final String KEY_QUERY = "query";
|
||||||
|
@ -81,7 +79,6 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
builder.field(KEY_EVENT_CATEGORY_FIELD, eventCategoryField());
|
builder.field(KEY_EVENT_CATEGORY_FIELD, eventCategoryField());
|
||||||
builder.field(KEY_SIZE, size());
|
builder.field(KEY_SIZE, size());
|
||||||
builder.field(KEY_FETCH_SIZE, fetchSize());
|
builder.field(KEY_FETCH_SIZE, fetchSize());
|
||||||
builder.field(KEY_CASE_SENSITIVE, isCaseSensitive());
|
|
||||||
|
|
||||||
builder.field(KEY_QUERY, query);
|
builder.field(KEY_QUERY, query);
|
||||||
if (waitForCompletionTimeout != null) {
|
if (waitForCompletionTimeout != null) {
|
||||||
|
@ -143,15 +140,6 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCaseSensitive() {
|
|
||||||
return this.isCaseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EqlSearchRequest isCaseSensitive(boolean isCaseSensitive) {
|
|
||||||
this.isCaseSensitive = isCaseSensitive;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return this.size;
|
return this.size;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +220,6 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
Objects.equals(tiebreakerField, that.tiebreakerField) &&
|
Objects.equals(tiebreakerField, that.tiebreakerField) &&
|
||||||
Objects.equals(eventCategoryField, that.eventCategoryField) &&
|
Objects.equals(eventCategoryField, that.eventCategoryField) &&
|
||||||
Objects.equals(query, that.query) &&
|
Objects.equals(query, that.query) &&
|
||||||
Objects.equals(isCaseSensitive, that.isCaseSensitive) &&
|
|
||||||
Objects.equals(waitForCompletionTimeout, that.waitForCompletionTimeout) &&
|
Objects.equals(waitForCompletionTimeout, that.waitForCompletionTimeout) &&
|
||||||
Objects.equals(keepAlive, that.keepAlive) &&
|
Objects.equals(keepAlive, that.keepAlive) &&
|
||||||
Objects.equals(keepOnCompletion, that.keepOnCompletion);
|
Objects.equals(keepOnCompletion, that.keepOnCompletion);
|
||||||
|
@ -250,7 +237,6 @@ public class EqlSearchRequest implements Validatable, ToXContentObject {
|
||||||
tiebreakerField,
|
tiebreakerField,
|
||||||
eventCategoryField,
|
eventCategoryField,
|
||||||
query,
|
query,
|
||||||
isCaseSensitive,
|
|
||||||
waitForCompletionTimeout,
|
waitForCompletionTimeout,
|
||||||
keepAlive,
|
keepAlive,
|
||||||
keepOnCompletion);
|
keepOnCompletion);
|
||||||
|
|
|
@ -486,34 +486,6 @@ GET /my-index-000001/_eql/search
|
||||||
----
|
----
|
||||||
// TEST[setup:sec_logs]
|
// TEST[setup:sec_logs]
|
||||||
|
|
||||||
[discrete]
|
|
||||||
[[eql-search-case-sensitive]]
|
|
||||||
=== Run a case-sensitive EQL search
|
|
||||||
|
|
||||||
By default, matching for EQL queries is case-insensitive. You can use the
|
|
||||||
`case_sensitive` parameter to toggle case sensitivity on or off.
|
|
||||||
|
|
||||||
The following search request contains a query that matches `process` events
|
|
||||||
with a `process.executable` containing `System32`.
|
|
||||||
|
|
||||||
Because `case_sensitive` is `true`, this query only matches `process.executable`
|
|
||||||
values containing `System32` with the exact same capitalization. A
|
|
||||||
`process.executable` value containing `system32` or `SYSTEM32` would not match
|
|
||||||
this query.
|
|
||||||
|
|
||||||
[source,console]
|
|
||||||
----
|
|
||||||
GET /my-index-000001/_eql/search
|
|
||||||
{
|
|
||||||
"keep_on_completion": true,
|
|
||||||
"case_sensitive": true,
|
|
||||||
"query": """
|
|
||||||
process where stringContains(process.executable, "System32")
|
|
||||||
"""
|
|
||||||
}
|
|
||||||
----
|
|
||||||
// TEST[setup:sec_logs]
|
|
||||||
|
|
||||||
[discrete]
|
[discrete]
|
||||||
[[eql-search-async]]
|
[[eql-search-async]]
|
||||||
=== Run an async EQL search
|
=== Run an async EQL search
|
||||||
|
|
|
@ -40,7 +40,6 @@ public abstract class BaseEqlSpecTestCase extends ESRestTestCase {
|
||||||
private final String query;
|
private final String query;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final long[] eventIds;
|
private final long[] eventIds;
|
||||||
private final boolean caseSensitive;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
private void setup() throws Exception {
|
private void setup() throws Exception {
|
||||||
|
@ -74,28 +73,22 @@ public abstract class BaseEqlSpecTestCase extends ESRestTestCase {
|
||||||
name = "" + (counter);
|
name = "" + (counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean[] values = spec.caseSensitive() == null ? new boolean[] { true, false } : new boolean[] { spec.caseSensitive() };
|
results.add(new Object[] { spec.query(), name, spec.expectedEventIds() });
|
||||||
|
|
||||||
for (boolean sensitive : values) {
|
|
||||||
String prefixed = name + (sensitive ? "-sensitive" : "-insensitive");
|
|
||||||
results.add(new Object[] { spec.query(), prefixed, spec.expectedEventIds(), sensitive });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseEqlSpecTestCase(String index, String query, String name, long[] eventIds, boolean caseSensitive) {
|
BaseEqlSpecTestCase(String index, String query, String name, long[] eventIds) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
|
|
||||||
this.query = query;
|
this.query = query;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.eventIds = eventIds;
|
this.eventIds = eventIds;
|
||||||
this.caseSensitive = caseSensitive;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() throws Exception {
|
public void test() throws Exception {
|
||||||
assertResponse(runQuery(index, query, caseSensitive));
|
assertResponse(runQuery(index, query));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertResponse(EqlSearchResponse response) {
|
protected void assertResponse(EqlSearchResponse response) {
|
||||||
|
@ -111,9 +104,8 @@ public abstract class BaseEqlSpecTestCase extends ESRestTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EqlSearchResponse runQuery(String index, String query, boolean isCaseSensitive) throws Exception {
|
protected EqlSearchResponse runQuery(String index, String query) throws Exception {
|
||||||
EqlSearchRequest request = new EqlSearchRequest(index, query);
|
EqlSearchRequest request = new EqlSearchRequest(index, query);
|
||||||
request.isCaseSensitive(isCaseSensitive);
|
|
||||||
request.tiebreakerField("event.sequence");
|
request.tiebreakerField("event.sequence");
|
||||||
// some queries return more than 10 results
|
// some queries return more than 10 results
|
||||||
request.size(50);
|
request.size(50);
|
||||||
|
|
|
@ -20,8 +20,8 @@ public abstract class EqlExtraSpecTestCase extends BaseEqlSpecTestCase {
|
||||||
return asArray(EqlSpecLoader.load("/test_extra.toml", true, new HashSet<>()));
|
return asArray(EqlSpecLoader.load("/test_extra.toml", true, new HashSet<>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EqlExtraSpecTestCase(String query, String name, long[] eventIds, boolean caseSensitive) {
|
public EqlExtraSpecTestCase(String query, String name, long[] eventIds) {
|
||||||
super(TEST_EXTRA_INDEX, query, name, eventIds, caseSensitive);
|
super(TEST_EXTRA_INDEX, query, name, eventIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,12 +19,6 @@ public class EqlSpec {
|
||||||
private String query;
|
private String query;
|
||||||
private long[] expectedEventIds;
|
private long[] expectedEventIds;
|
||||||
|
|
||||||
// flag to dictate which modes are supported for the test
|
|
||||||
// null -> apply the test to both modes (case sensitive and case insensitive)
|
|
||||||
// TRUE -> case sensitive
|
|
||||||
// FALSE -> case insensitive
|
|
||||||
private Boolean caseSensitive = null;
|
|
||||||
|
|
||||||
public String name() {
|
public String name() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -73,14 +67,6 @@ public class EqlSpec {
|
||||||
this.expectedEventIds = expectedEventIds;
|
this.expectedEventIds = expectedEventIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void caseSensitive(Boolean caseSensitive) {
|
|
||||||
this.caseSensitive = caseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean caseSensitive() {
|
|
||||||
return this.caseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public EqlSpec withSensitivity(boolean caseSensitive) {
|
public EqlSpec withSensitivity(boolean caseSensitive) {
|
||||||
EqlSpec spec = new EqlSpec();
|
EqlSpec spec = new EqlSpec();
|
||||||
spec.name = name;
|
spec.name = name;
|
||||||
|
@ -90,7 +76,6 @@ public class EqlSpec {
|
||||||
spec.query = query;
|
spec.query = query;
|
||||||
spec.expectedEventIds = expectedEventIds;
|
spec.expectedEventIds = expectedEventIds;
|
||||||
|
|
||||||
spec.caseSensitive = caseSensitive;
|
|
||||||
return spec;
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,10 +87,6 @@ public class EqlSpec {
|
||||||
str = appendWithComma(str, "description", description);
|
str = appendWithComma(str, "description", description);
|
||||||
str = appendWithComma(str, "note", note);
|
str = appendWithComma(str, "note", note);
|
||||||
|
|
||||||
if (caseSensitive != null) {
|
|
||||||
str = appendWithComma(str, "case_sensitive", Boolean.toString(caseSensitive));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tags != null) {
|
if (tags != null) {
|
||||||
str = appendWithComma(str, "tags", Arrays.toString(tags));
|
str = appendWithComma(str, "tags", Arrays.toString(tags));
|
||||||
}
|
}
|
||||||
|
@ -128,13 +109,12 @@ public class EqlSpec {
|
||||||
|
|
||||||
EqlSpec that = (EqlSpec) other;
|
EqlSpec that = (EqlSpec) other;
|
||||||
|
|
||||||
return Objects.equals(this.query(), that.query())
|
return Objects.equals(this.query(), that.query());
|
||||||
&& Objects.equals(this.caseSensitive, that.caseSensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(this.query, this.caseSensitive);
|
return Objects.hash(this.query);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String appendWithComma(String str, String name, String append) {
|
private static String appendWithComma(String str, String name, String append) {
|
||||||
|
|
|
@ -73,20 +73,6 @@ public class EqlSpecLoader {
|
||||||
spec.note(getTrimmedString(table, "note"));
|
spec.note(getTrimmedString(table, "note"));
|
||||||
spec.description(getTrimmedString(table, "description"));
|
spec.description(getTrimmedString(table, "description"));
|
||||||
|
|
||||||
Boolean caseSensitive = table.getBoolean("case_sensitive");
|
|
||||||
Boolean caseInsensitive = table.getBoolean("case_insensitive");
|
|
||||||
// if case_sensitive is TRUE and case_insensitive is not TRUE (FALSE or NULL), then the test is case sensitive only
|
|
||||||
if (Boolean.TRUE.equals(caseSensitive)) {
|
|
||||||
if (Boolean.FALSE.equals(caseInsensitive) || caseInsensitive == null) {
|
|
||||||
spec.caseSensitive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if case_sensitive is not TRUE (FALSE or NULL) and case_insensitive is TRUE, then the test is case insensitive only
|
|
||||||
else if (Boolean.TRUE.equals(caseInsensitive)) {
|
|
||||||
spec.caseSensitive(false);
|
|
||||||
}
|
|
||||||
// in all other cases, the test should run no matter the case sensitivity (should test both scenarios)
|
|
||||||
|
|
||||||
List<?> arr = table.getList("tags");
|
List<?> arr = table.getList("tags");
|
||||||
if (arr != null) {
|
if (arr != null) {
|
||||||
String tags[] = new String[arr.size()];
|
String tags[] = new String[arr.size()];
|
||||||
|
|
|
@ -51,7 +51,7 @@ public abstract class EqlSpecTestCase extends BaseEqlSpecTestCase {
|
||||||
return "serial_event_id";
|
return "serial_event_id";
|
||||||
}
|
}
|
||||||
|
|
||||||
public EqlSpecTestCase(String query, String name, long[] eventIds, boolean caseSensitive) {
|
public EqlSpecTestCase(String query, String name, long[] eventIds) {
|
||||||
super(TEST_INDEX, query, name, eventIds, caseSensitive);
|
super(TEST_INDEX, query, name, eventIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,13 +177,11 @@ expected_event_ids = [1, 2]
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "compareTwoFields1"
|
name = "compareTwoFields1"
|
||||||
# test that it works for comparing field <--> field
|
# test that it works for comparing field <--> field
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
||||||
expected_event_ids = [2, 3]
|
expected_event_ids = [2, 3]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "compareTwoFields2"
|
name = "compareTwoFields2"
|
||||||
case_sensitive = true
|
|
||||||
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
||||||
expected_event_ids = [2]
|
expected_event_ids = [2]
|
||||||
|
|
||||||
|
@ -219,39 +217,33 @@ expected_event_ids = [1]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseSensitive1"
|
name = "processWithStringComparisonCaseSensitive1"
|
||||||
case_sensitive = true
|
|
||||||
notes = "s == 0x73; S == 0x53"
|
notes = "s == 0x73; S == 0x53"
|
||||||
query = 'process where process_name >= "system idle process" and process_name <= "System Idle Process"'
|
query = 'process where process_name >= "system idle process" and process_name <= "System Idle Process"'
|
||||||
expected_event_ids = []
|
expected_event_ids = []
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive1"
|
name = "processWithStringComparisonCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "system idle process" and process_name <= "System Idle Process"'
|
query = 'process where process_name >= "system idle process" and process_name <= "System Idle Process"'
|
||||||
expected_event_ids = [1]
|
expected_event_ids = [1]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive2"
|
name = "processWithStringComparisonCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "SYSTE" and process_name < "systex"'
|
query = 'process where process_name >= "SYSTE" and process_name < "systex"'
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive3"
|
name = "processWithStringComparisonCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "sysT" and process_name < "SYsTeZZZ"'
|
query = 'process where process_name >= "sysT" and process_name < "SYsTeZZZ"'
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive4"
|
name = "processWithStringComparisonCaseInsensitive4"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "SYSTE" and process_name <= "systex"'
|
query = 'process where process_name >= "SYSTE" and process_name <= "systex"'
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
|
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringEqualityCaseInsensitive1"
|
name = "processWithStringEqualityCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name : "VMACTHLP.exe" and unique_pid == 12
|
process where process_name : "VMACTHLP.exe" and unique_pid == 12
|
||||||
| filter true
|
| filter true
|
||||||
|
@ -268,7 +260,6 @@ expected_event_ids = [3, 34, 48]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processNameINCaseInsensitive1"
|
name = "processNameINCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name in ("python.exe", "SMSS.exe", "explorer.exe")
|
process where process_name in ("python.exe", "SMSS.exe", "explorer.exe")
|
||||||
| unique process_name
|
| unique process_name
|
||||||
|
@ -277,7 +268,6 @@ expected_event_ids = [3, 34, 48]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processNameINCaseInsensitive2"
|
name = "processNameINCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name in ("python.exe", "smss.exe", "Explorer.exe")
|
process where process_name in ("python.exe", "smss.exe", "Explorer.exe")
|
||||||
| unique length(process_name)
|
| unique length(process_name)
|
||||||
|
@ -294,7 +284,6 @@ expected_event_ids = [3, 48]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processNameINWithUnique2"
|
name = "processNameINWithUnique2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name in ("Python.exe", "smss.exe", "explorer.exe")
|
process where process_name in ("Python.exe", "smss.exe", "explorer.exe")
|
||||||
| unique process_name != "python.exe"
|
| unique process_name != "python.exe"
|
||||||
|
@ -348,7 +337,6 @@ expected_event_ids = [3, 48, 50, 54]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseInsensitive1"
|
name = "lengthCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where length(bytes_written_string_list) == 2 and bytes_written_string_list[1] : "EN"
|
registry where length(bytes_written_string_list) == 2 and bytes_written_string_list[1] : "EN"
|
||||||
|
@ -446,7 +434,6 @@ expected_event_ids = [2, 50, 51]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "twoINsCaseInsensitive"
|
name = "twoINsCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where opcode in (1,3) and process_name in (parent_process_name, "SYSTEM")
|
process where opcode in (1,3) and process_name in (parent_process_name, "SYSTEM")
|
||||||
'''
|
'''
|
||||||
|
@ -454,7 +441,6 @@ expected_event_ids = [2, 50, 51]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "simpleTailWithSort"
|
name = "simpleTailWithSort"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [92, 95, 96, 91]
|
expected_event_ids = [92, 95, 96, 91]
|
||||||
query = '''
|
query = '''
|
||||||
file where true
|
file where true
|
||||||
|
@ -1319,7 +1305,6 @@ any where process_name : "svchost.exe"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive1"
|
name = "arrayContainsCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "En-uS")
|
registry where arrayContains(bytes_written_string_list, "En-uS")
|
||||||
|
@ -1327,7 +1312,6 @@ registry where arrayContains(bytes_written_string_list, "En-uS")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive2"
|
name = "arrayContainsCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "En")
|
registry where arrayContains(bytes_written_string_list, "En")
|
||||||
|
@ -1335,7 +1319,6 @@ registry where arrayContains(bytes_written_string_list, "En")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseInsensitive2"
|
name = "lengthCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "EN-us"
|
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "EN-us"
|
||||||
|
@ -1343,7 +1326,6 @@ registry where length(bytes_written_string_list) > 0 and bytes_written_string_li
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCaseInsensitive1"
|
name = "arrayCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where bytes_written_string_list[0] : "EN-us"
|
registry where bytes_written_string_list[0] : "EN-us"
|
||||||
|
@ -1351,7 +1333,6 @@ registry where bytes_written_string_list[0] : "EN-us"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCaseInsensitive2"
|
name = "arrayCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where bytes_written_string_list[1] : "EN"
|
registry where bytes_written_string_list[1] : "EN"
|
||||||
|
@ -1360,7 +1341,6 @@ registry where bytes_written_string_list[1] : "EN"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive3"
|
name = "arrayContainsCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "en-US")
|
registry where arrayContains(bytes_written_string_list, "en-US")
|
||||||
|
@ -1368,7 +1348,6 @@ registry where arrayContains(bytes_written_string_list, "en-US")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive4"
|
name = "arrayContainsCaseInsensitive4"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "en")
|
registry where arrayContains(bytes_written_string_list, "en")
|
||||||
|
@ -1376,7 +1355,6 @@ registry where arrayContains(bytes_written_string_list, "en")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCaseInsensitive3"
|
name = "arrayCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "en-US"
|
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "en-US"
|
||||||
|
@ -1433,7 +1411,6 @@ expected_event_ids = [98]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "stringEqualsCaseInsensitive1"
|
name = "stringEqualsCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where "net.EXE" == original_file_name
|
process where "net.EXE" == original_file_name
|
||||||
| filter process_name:"net*.exe"
|
| filter process_name:"net*.exe"
|
||||||
|
@ -1443,7 +1420,6 @@ note = "check that case insensitive comparisons are performed even for lhs strin
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "stringEqualsCaseInsensitive2"
|
name = "stringEqualsCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name == original_file_name and process_name:"net*.exe"
|
process where process_name == original_file_name and process_name:"net*.exe"
|
||||||
'''
|
'''
|
||||||
|
@ -1452,7 +1428,6 @@ note = "check that case insensitive comparisons are performed for fields."
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "fieldsComparisonCaseInsensitive"
|
name = "fieldsComparisonCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where original_file_name == process_name and length(original_file_name) > 0
|
process where original_file_name == process_name and length(original_file_name) > 0
|
||||||
'''
|
'''
|
||||||
|
@ -1461,17 +1436,14 @@ description = "check that case insensitive comparisons are performed for fields.
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "startsWithCaseSensitive"
|
name = "startsWithCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and startsWith(file_name, "explorer.")
|
file where opcode==0 and startsWith(file_name, "explorer.")
|
||||||
'''
|
'''
|
||||||
expected_event_ids = [88]
|
expected_event_ids = [88]
|
||||||
description = "check built-in string functions"
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "startsWithCaseInsensitive1"
|
name = "startsWithCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and startsWith(file_name, "explorer.")
|
file where opcode==0 and startsWith(file_name, "explorer.")
|
||||||
'''
|
'''
|
||||||
|
@ -1481,7 +1453,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "startsWithCaseInsensitive2"
|
name = "startsWithCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and startsWith(file_name, "exploRER.")
|
file where opcode==0 and startsWith(file_name, "exploRER.")
|
||||||
'''
|
'''
|
||||||
|
@ -1490,7 +1461,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "startsWithCaseInsensitive3"
|
name = "startsWithCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and startsWith(file_name, "expLORER.exe")
|
file where opcode==0 and startsWith(file_name, "expLORER.exe")
|
||||||
'''
|
'''
|
||||||
|
@ -1508,7 +1478,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "endsWithCaseInsensitive"
|
name = "endsWithCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and endsWith(file_name, "loREr.exe")
|
file where opcode==0 and endsWith(file_name, "loREr.exe")
|
||||||
'''
|
'''
|
||||||
|
@ -1525,7 +1494,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "endsWithAndCondition"
|
name = "endsWithAndCondition"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and serial_event_id == 88 and startsWith("explorer.exeaAAAA", "EXPLORER.exe")
|
file where opcode==0 and serial_event_id == 88 and startsWith("explorer.exeaAAAA", "EXPLORER.exe")
|
||||||
'''
|
'''
|
||||||
|
@ -1542,7 +1510,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOfCaseInsensitive"
|
name = "indexOfCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plore") == 2 and indexOf(file_name, ".pf") == null
|
file where opcode==0 and indexOf(file_name, "plore") == 2 and indexOf(file_name, ".pf") == null
|
||||||
'''
|
'''
|
||||||
|
@ -1559,7 +1526,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf2"
|
name = "indexOf2"
|
||||||
case_sensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plorer.", 0) == 2
|
file where opcode==0 and indexOf(file_name, "plorer.", 0) == 2
|
||||||
'''
|
'''
|
||||||
|
@ -1568,7 +1534,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf3"
|
name = "indexOf3"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plorer.", 0) == 2
|
file where opcode==0 and indexOf(file_name, "plorer.", 0) == 2
|
||||||
'''
|
'''
|
||||||
|
@ -1577,7 +1542,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf4"
|
name = "indexOf4"
|
||||||
case_sensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plorer.", 2) != null
|
file where opcode==0 and indexOf(file_name, "plorer.", 2) != null
|
||||||
'''
|
'''
|
||||||
|
@ -1586,7 +1550,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf5"
|
name = "indexOf5"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plorer.", 2) != null
|
file where opcode==0 and indexOf(file_name, "plorer.", 2) != null
|
||||||
'''
|
'''
|
||||||
|
@ -1611,7 +1574,6 @@ description = "check built-in string functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf8"
|
name = "indexOf8"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plorer.", 2) == 2
|
file where opcode==0 and indexOf(file_name, "plorer.", 2) == 2
|
||||||
'''
|
'''
|
||||||
|
@ -1620,7 +1582,6 @@ description = "check substring ranges"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf9"
|
name = "indexOf9"
|
||||||
case_sensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "plorer.", 2) == 2
|
file where opcode==0 and indexOf(file_name, "plorer.", 2) == 2
|
||||||
'''
|
'''
|
||||||
|
@ -1629,7 +1590,6 @@ description = "check substring ranges"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf10"
|
name = "indexOf10"
|
||||||
case_sensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "explorer.", 0) == 0
|
file where opcode==0 and indexOf(file_name, "explorer.", 0) == 0
|
||||||
'''
|
'''
|
||||||
|
@ -1638,7 +1598,6 @@ description = "check substring ranges"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "indexOf11"
|
name = "indexOf11"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where opcode==0 and indexOf(file_name, "explorer.", 0) == 0
|
file where opcode==0 and indexOf(file_name, "explorer.", 0) == 0
|
||||||
'''
|
'''
|
||||||
|
@ -1647,7 +1606,6 @@ description = "check substring ranges"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "substring1"
|
name = "substring1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where serial_event_id==88 and substring(file_name, 0, 4) : "expl"
|
file where serial_event_id==88 and substring(file_name, 0, 4) : "expl"
|
||||||
'''
|
'''
|
||||||
|
@ -1656,7 +1614,6 @@ description = "check substring ranges"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "substring2"
|
name = "substring2"
|
||||||
case_sensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where substring(file_name, 1, 3) == "xp"
|
file where substring(file_name, 1, 3) == "xp"
|
||||||
'''
|
'''
|
||||||
|
@ -1665,7 +1622,6 @@ description = "check substring ranges"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "substring3"
|
name = "substring3"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where substring(file_name, 1, 3) : "xp"
|
file where substring(file_name, 1, 3) : "xp"
|
||||||
'''
|
'''
|
||||||
|
@ -1754,7 +1710,6 @@ description = "test string concatenation"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "concatCaseInsensitive"
|
name = "concatCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where concat(serial_event_id, ":", process_name, opcode) : "5:winINIT.exe3"
|
process where concat(serial_event_id, ":", process_name, opcode) : "5:winINIT.exe3"
|
||||||
'''
|
'''
|
||||||
|
@ -1763,7 +1718,6 @@ description = "test string concatenation"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "fieldComparisonCaseInsensitive"
|
name = "fieldComparisonCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name != original_file_name and length(original_file_name) > 0
|
process where process_name != original_file_name and length(original_file_name) > 0
|
||||||
'''
|
'''
|
||||||
|
@ -1781,7 +1735,6 @@ registry where arraySearch(bytes_written_string_list, a, a : "en-US")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arraySearchCaseSensitive"
|
name = "arraySearchCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
expected_event_ids = []
|
expected_event_ids = []
|
||||||
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -1790,7 +1743,6 @@ registry where arraySearch(bytes_written_string_list, a, a : "EN-US")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arraySearchCaseInsensitive1"
|
name = "arraySearchCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -1799,7 +1751,6 @@ registry where arraySearch(bytes_written_string_list, a, a : "en-us")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arraySearchCaseInsensitive2"
|
name = "arraySearchCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -1889,7 +1840,6 @@ network where safe(divide(process_name, process_name))
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "nestedSetComparisons"
|
name = "nestedSetComparisons"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where serial_event_id == 82 and (true == (process_name in ("svchost.EXE", "bad.exe", "bad2.exe")))
|
file where serial_event_id == 82 and (true == (process_name in ("svchost.EXE", "bad.exe", "bad2.exe")))
|
||||||
'''
|
'''
|
||||||
|
@ -1898,7 +1848,6 @@ description = "nested set comparisons"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCount1"
|
name = "arrayCount1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayCount(bytes_written_string_list, s, s : "*-us") == 1
|
registry where arrayCount(bytes_written_string_list, s, s : "*-us") == 1
|
||||||
|
@ -1906,7 +1855,6 @@ registry where arrayCount(bytes_written_string_list, s, s : "*-us") == 1
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCount2"
|
name = "arrayCount2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayCount(bytes_written_string_list, s, s : "*en*") == 2
|
registry where arrayCount(bytes_written_string_list, s, s : "*en*") == 2
|
||||||
|
@ -1914,7 +1862,6 @@ registry where arrayCount(bytes_written_string_list, s, s : "*en*") == 2
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive5"
|
name = "arrayContainsCaseInsensitive5"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "missing", "en-US")
|
registry where arrayContains(bytes_written_string_list, "missing", "en-US")
|
||||||
|
@ -1952,7 +1899,6 @@ query = "file where serial_event_id % 40 == 2"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "betweenCaseInsensitive1"
|
name = "betweenCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
query = '''
|
query = '''
|
||||||
process where between(process_name, "s", "e") : "yst"
|
process where between(process_name, "s", "e") : "yst"
|
||||||
|
@ -1960,7 +1906,6 @@ process where between(process_name, "s", "e") : "yst"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "betweenCaseInsensitive2"
|
name = "betweenCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
query = '''
|
query = '''
|
||||||
process where between(process_name, "s", "e", false) : "yst"
|
process where between(process_name, "s", "e", false) : "yst"
|
||||||
|
@ -1968,7 +1913,6 @@ process where between(process_name, "s", "e", false) : "yst"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "betweenCaseSensitive"
|
name = "betweenCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
expected_event_ids = [1, 2, 42]
|
expected_event_ids = [1, 2, 42]
|
||||||
query = '''
|
query = '''
|
||||||
process where between(process_name, "s", "e", false) : "t"
|
process where between(process_name, "s", "e", false) : "t"
|
||||||
|
@ -1983,7 +1927,6 @@ process where between(process_name, "S", "e", true) : "ystem Idle Proc"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "betweenCaseInsensitive3"
|
name = "betweenCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [1]
|
expected_event_ids = [1]
|
||||||
query = '''
|
query = '''
|
||||||
process where between(process_name, "s", "e", true) : "ystem Idle Proc"
|
process where between(process_name, "s", "e", true) : "ystem Idle Proc"
|
||||||
|
@ -2034,7 +1977,6 @@ network where cidrMatch(source_address, "0.0.0.0/0")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseSensitive"
|
name = "lengthCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
expected_event_ids = [7, 14, 29, 44]
|
expected_event_ids = [7, 14, 29, 44]
|
||||||
query = '''
|
query = '''
|
||||||
process where length(between(process_name, "g", "e")) > 0
|
process where length(between(process_name, "g", "e")) > 0
|
||||||
|
@ -2042,7 +1984,6 @@ process where length(between(process_name, "g", "e")) > 0
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseInsensitiveAndBetween"
|
name = "lengthCaseInsensitiveAndBetween"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [7, 14, 22, 29, 44]
|
expected_event_ids = [7, 14, 22, 29, 44]
|
||||||
query = '''
|
query = '''
|
||||||
process where length(between(process_name, "g", "e")) > 0
|
process where length(between(process_name, "g", "e")) > 0
|
||||||
|
|
|
@ -8,6 +8,99 @@
|
||||||
# in order to allow at least one round-trip test with the test harness.
|
# in order to allow at least one round-trip test with the test harness.
|
||||||
# This will be removed once the EQL implementation is wired and actually supports this query.
|
# This will be removed once the EQL implementation is wired and actually supports this query.
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "startsWithCaseInsensitive1"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and startsWith(file_name, "explorer.")
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "startsWithCaseInsensitive2"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and startsWith(file_name, "exploRER.")
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "startsWithCaseInsensitive3"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and startsWith(file_name, "expLORER.exe")
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "endsWithCaseInsensitive"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and endsWith(file_name, "loREr.exe")
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "endsWithAndCondition"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and serial_event_id == 88 and startsWith("explorer.exeaAAAA", "EXPLORER.exe")
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "indexOf3"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and indexOf(file_name, "plorer.", 0) == 2
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "indexOf5"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and indexOf(file_name, "plorer.", 2) != null
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check built-in string functions"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "indexOf8"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and indexOf(file_name, "plorer.", 2) == 2
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check substring ranges"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "indexOf11"
|
||||||
|
query = '''
|
||||||
|
file where opcode==0 and indexOf(file_name, "explorer.", 0) == 0
|
||||||
|
'''
|
||||||
|
expected_event_ids = [88, 92]
|
||||||
|
description = "check substring ranges"
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "betweenCaseInsensitive1"
|
||||||
|
expected_event_ids = [1, 2]
|
||||||
|
query = '''
|
||||||
|
process where between(process_name, "s", "e") : "yst"
|
||||||
|
'''
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "betweenCaseInsensitive2"
|
||||||
|
expected_event_ids = [1, 2]
|
||||||
|
query = '''
|
||||||
|
process where between(process_name, "s", "e", false) : "yst"
|
||||||
|
'''
|
||||||
|
|
||||||
|
[[queries]]
|
||||||
|
name = "betweenCaseInsensitive3"
|
||||||
|
expected_event_ids = [1]
|
||||||
|
query = '''
|
||||||
|
process where between(process_name, "s", "e", true) : "ystem Idle Proc"
|
||||||
|
'''
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "twoSequencesWithKeys"
|
name = "twoSequencesWithKeys"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -93,13 +186,11 @@ expected_event_ids = [7, 8]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "compareTwoFields1"
|
name = "compareTwoFields1"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
||||||
expected_event_ids = [2, 3]
|
expected_event_ids = [2, 3]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "compareTwoFields2"
|
name = "compareTwoFields2"
|
||||||
case_sensitive = true
|
|
||||||
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
query = 'process where serial_event_id < 5 and process_name <= parent_process_name'
|
||||||
expected_event_ids = [2]
|
expected_event_ids = [2]
|
||||||
|
|
||||||
|
@ -107,32 +198,27 @@ expected_event_ids = [2]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive1"
|
name = "processWithStringComparisonCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "system idle process" and process_name <= "System Idle Process"'
|
query = 'process where process_name >= "system idle process" and process_name <= "System Idle Process"'
|
||||||
expected_event_ids = [1]
|
expected_event_ids = [1]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive2"
|
name = "processWithStringComparisonCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "SYSTE" and process_name < "systex"'
|
query = 'process where process_name >= "SYSTE" and process_name < "systex"'
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive3"
|
name = "processWithStringComparisonCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "sysT" and process_name < "SYsTeZZZ"'
|
query = 'process where process_name >= "sysT" and process_name < "SYsTeZZZ"'
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringComparisonCaseInsensitive4"
|
name = "processWithStringComparisonCaseInsensitive4"
|
||||||
case_insensitive = true
|
|
||||||
query = 'process where process_name >= "SYSTE" and process_name <= "systex"'
|
query = 'process where process_name >= "SYSTE" and process_name <= "systex"'
|
||||||
expected_event_ids = [1, 2]
|
expected_event_ids = [1, 2]
|
||||||
|
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processWithStringEqualityCaseInsensitive1"
|
name = "processWithStringEqualityCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name : "VMACTHLP.exe" and unique_pid == 12
|
process where process_name : "VMACTHLP.exe" and unique_pid == 12
|
||||||
| filter true
|
| filter true
|
||||||
|
@ -149,7 +235,6 @@ expected_event_ids = [3, 34, 48]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processNameINCaseInsensitive1"
|
name = "processNameINCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name in ("python.exe", "SMSS.exe", "explorer.exe")
|
process where process_name in ("python.exe", "SMSS.exe", "explorer.exe")
|
||||||
| unique process_name
|
| unique process_name
|
||||||
|
@ -158,7 +243,6 @@ expected_event_ids = [3, 34, 48]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processNameINCaseInsensitive2"
|
name = "processNameINCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name in ("python.exe", "smss.exe", "Explorer.exe")
|
process where process_name in ("python.exe", "smss.exe", "Explorer.exe")
|
||||||
| unique length(process_name)
|
| unique length(process_name)
|
||||||
|
@ -175,7 +259,6 @@ expected_event_ids = [3, 48]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "processNameINWithUnique2"
|
name = "processNameINWithUnique2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name in ("Python.exe", "smss.exe", "explorer.exe")
|
process where process_name in ("Python.exe", "smss.exe", "explorer.exe")
|
||||||
| unique process_name != "python.exe"
|
| unique process_name != "python.exe"
|
||||||
|
@ -229,7 +312,6 @@ expected_event_ids = [3, 48, 50, 54]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseInsensitive"
|
name = "lengthCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where length(bytes_written_string_list) == 2 and bytes_written_string_list[1] : "EN"
|
registry where length(bytes_written_string_list) == 2 and bytes_written_string_list[1] : "EN"
|
||||||
|
@ -282,7 +364,6 @@ expected_event_ids = [2, 50, 51]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "twoINsCaseInsensitive"
|
name = "twoINsCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where opcode in (1,3) and process_name in (parent_process_name, "SYSTEM")
|
process where opcode in (1,3) and process_name in (parent_process_name, "SYSTEM")
|
||||||
'''
|
'''
|
||||||
|
@ -290,7 +371,6 @@ expected_event_ids = [2, 50, 51]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "simpleTailWithSort"
|
name = "simpleTailWithSort"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [92, 95, 96, 91]
|
expected_event_ids = [92, 95, 96, 91]
|
||||||
query = '''
|
query = '''
|
||||||
file where true
|
file where true
|
||||||
|
@ -716,7 +796,6 @@ any where process_name : "svchost.exe"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive1"
|
name = "arrayContainsCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "En-uS")
|
registry where arrayContains(bytes_written_string_list, "En-uS")
|
||||||
|
@ -724,7 +803,6 @@ registry where arrayContains(bytes_written_string_list, "En-uS")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive2"
|
name = "arrayContainsCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "En")
|
registry where arrayContains(bytes_written_string_list, "En")
|
||||||
|
@ -732,7 +810,6 @@ registry where arrayContains(bytes_written_string_list, "En")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseInsensitive"
|
name = "lengthCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "EN-us"
|
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "EN-us"
|
||||||
|
@ -740,7 +817,6 @@ registry where length(bytes_written_string_list) > 0 and bytes_written_string_li
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCaseInsensitive1"
|
name = "arrayCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where bytes_written_string_list[0] : "EN-us"
|
registry where bytes_written_string_list[0] : "EN-us"
|
||||||
|
@ -748,7 +824,6 @@ registry where bytes_written_string_list[0] : "EN-us"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCaseInsensitive2"
|
name = "arrayCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where bytes_written_string_list[1] : "EN"
|
registry where bytes_written_string_list[1] : "EN"
|
||||||
|
@ -757,7 +832,6 @@ registry where bytes_written_string_list[1] : "EN"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive3"
|
name = "arrayContainsCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "en-US")
|
registry where arrayContains(bytes_written_string_list, "en-US")
|
||||||
|
@ -765,7 +839,6 @@ registry where arrayContains(bytes_written_string_list, "en-US")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive4"
|
name = "arrayContainsCaseInsensitive4"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "en")
|
registry where arrayContains(bytes_written_string_list, "en")
|
||||||
|
@ -773,7 +846,6 @@ registry where arrayContains(bytes_written_string_list, "en")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCaseInsensitive3"
|
name = "arrayCaseInsensitive3"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "en-US"
|
registry where length(bytes_written_string_list) > 0 and bytes_written_string_list[0] : "en-US"
|
||||||
|
@ -831,7 +903,6 @@ expected_event_ids = [98]
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "stringEqualsCaseInsensitive1"
|
name = "stringEqualsCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where "net.EXE" == original_file_name
|
process where "net.EXE" == original_file_name
|
||||||
| filter process_name:"net*.exe"
|
| filter process_name:"net*.exe"
|
||||||
|
@ -841,7 +912,6 @@ note = "check that case insensitive comparisons are performed even for lhs strin
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "stringEqualsCaseInsensitive2"
|
name = "stringEqualsCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name == original_file_name and process_name:"net*.exe"
|
process where process_name == original_file_name and process_name:"net*.exe"
|
||||||
'''
|
'''
|
||||||
|
@ -850,7 +920,6 @@ note = "check that case insensitive comparisons are performed for fields."
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "fieldsComparisonCaseInsensitive"
|
name = "fieldsComparisonCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where original_file_name == process_name and length(original_file_name) > 0
|
process where original_file_name == process_name and length(original_file_name) > 0
|
||||||
'''
|
'''
|
||||||
|
@ -859,7 +928,6 @@ description = "check that case insensitive comparisons are performed for fields.
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "substring3"
|
name = "substring3"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where substring(file_name, 1, 3) : "xp"
|
file where substring(file_name, 1, 3) : "xp"
|
||||||
'''
|
'''
|
||||||
|
@ -876,7 +944,6 @@ description = "test built-in math functions"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "concatCaseInsensitive"
|
name = "concatCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where concat(serial_event_id, ":", process_name, opcode) : "5:winINIT.exe3"
|
process where concat(serial_event_id, ":", process_name, opcode) : "5:winINIT.exe3"
|
||||||
'''
|
'''
|
||||||
|
@ -885,7 +952,6 @@ description = "test string concatenation"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "fieldComparisonCaseInsensitive"
|
name = "fieldComparisonCaseInsensitive"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
process where process_name != original_file_name and length(original_file_name) > 0
|
process where process_name != original_file_name and length(original_file_name) > 0
|
||||||
'''
|
'''
|
||||||
|
@ -903,7 +969,6 @@ registry where arraySearch(bytes_written_string_list, a, a : "en-US")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arraySearchCaseSensitive"
|
name = "arraySearchCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
expected_event_ids = []
|
expected_event_ids = []
|
||||||
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -912,7 +977,6 @@ registry where arraySearch(bytes_written_string_list, a, a : "EN-US")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arraySearchCaseInsensitive1"
|
name = "arraySearchCaseInsensitive1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -921,7 +985,6 @@ registry where arraySearch(bytes_written_string_list, a, a : "en-us")
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arraySearchCaseInsensitive2"
|
name = "arraySearchCaseInsensitive2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
description = "test arraySearch functionality for lists of strings, and lists of objects"
|
||||||
query = '''
|
query = '''
|
||||||
|
@ -1011,7 +1074,6 @@ network where safe(divide(process_name, process_name))
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "nestedSetComparisons"
|
name = "nestedSetComparisons"
|
||||||
case_insensitive = true
|
|
||||||
query = '''
|
query = '''
|
||||||
file where serial_event_id == 82 and (true == (process_name in ("svchost.EXE", "bad.exe", "bad2.exe")))
|
file where serial_event_id == 82 and (true == (process_name in ("svchost.EXE", "bad.exe", "bad2.exe")))
|
||||||
'''
|
'''
|
||||||
|
@ -1020,7 +1082,6 @@ description = "nested set comparisons"
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCount1"
|
name = "arrayCount1"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayCount(bytes_written_string_list, s, s : "*-us") == 1
|
registry where arrayCount(bytes_written_string_list, s, s : "*-us") == 1
|
||||||
|
@ -1028,7 +1089,6 @@ registry where arrayCount(bytes_written_string_list, s, s : "*-us") == 1
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayCount2"
|
name = "arrayCount2"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayCount(bytes_written_string_list, s, s : "*en*") == 2
|
registry where arrayCount(bytes_written_string_list, s, s : "*en*") == 2
|
||||||
|
@ -1036,7 +1096,6 @@ registry where arrayCount(bytes_written_string_list, s, s : "*en*") == 2
|
||||||
|
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "arrayContainsCaseInsensitive5"
|
name = "arrayContainsCaseInsensitive5"
|
||||||
case_insensitive = true
|
|
||||||
expected_event_ids = [57]
|
expected_event_ids = [57]
|
||||||
query = '''
|
query = '''
|
||||||
registry where arrayContains(bytes_written_string_list, "missing", "en-US")
|
registry where arrayContains(bytes_written_string_list, "missing", "en-US")
|
||||||
|
@ -1069,7 +1128,6 @@ expected_event_ids = [1, 2,
|
||||||
# TODO: update toggles for this function
|
# TODO: update toggles for this function
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "betweenCaseSensitive"
|
name = "betweenCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
expected_event_ids = [1, 2, 42]
|
expected_event_ids = [1, 2, 42]
|
||||||
query = '''
|
query = '''
|
||||||
process where between(process_name, "s", "e", false) : "t"
|
process where between(process_name, "s", "e", false) : "t"
|
||||||
|
@ -1078,7 +1136,6 @@ process where between(process_name, "s", "e", false) : "t"
|
||||||
# TODO: add toggles to this function so it's not always insensitive
|
# TODO: add toggles to this function so it's not always insensitive
|
||||||
[[queries]]
|
[[queries]]
|
||||||
name = "lengthCaseSensitive"
|
name = "lengthCaseSensitive"
|
||||||
case_sensitive = true
|
|
||||||
expected_event_ids = [7, 14, 29, 44]
|
expected_event_ids = [7, 14, 29, 44]
|
||||||
query = '''
|
query = '''
|
||||||
process where length(between(process_name, "g", "e")) > 0
|
process where length(between(process_name, "g", "e")) > 0
|
||||||
|
|
|
@ -12,7 +12,7 @@ import org.elasticsearch.test.junit.annotations.TestLogging;
|
||||||
@TestLogging(value = "org.elasticsearch.xpack.eql:TRACE", reason = "results logging")
|
@TestLogging(value = "org.elasticsearch.xpack.eql:TRACE", reason = "results logging")
|
||||||
public class EqlExtraIT extends EqlExtraSpecTestCase {
|
public class EqlExtraIT extends EqlExtraSpecTestCase {
|
||||||
|
|
||||||
public EqlExtraIT(String query, String name, long[] eventIds, boolean caseSensitive) {
|
public EqlExtraIT(String query, String name, long[] eventIds) {
|
||||||
super(query, name, eventIds, caseSensitive);
|
super(query, name, eventIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import org.elasticsearch.test.eql.EqlSpecTestCase;
|
||||||
|
|
||||||
public class EqlSpecIT extends EqlSpecTestCase {
|
public class EqlSpecIT extends EqlSpecTestCase {
|
||||||
|
|
||||||
public EqlSpecIT(String query, String name, long[] eventIds, boolean caseSensitive) {
|
public EqlSpecIT(String query, String name, long[] eventIds) {
|
||||||
super(query, name, eventIds, caseSensitive);
|
super(query, name, eventIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,6 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
private int size = RequestDefaults.SIZE;
|
private int size = RequestDefaults.SIZE;
|
||||||
private int fetchSize = RequestDefaults.FETCH_SIZE;
|
private int fetchSize = RequestDefaults.FETCH_SIZE;
|
||||||
private String query;
|
private String query;
|
||||||
private boolean isCaseSensitive = false;
|
|
||||||
|
|
||||||
// Async settings
|
// Async settings
|
||||||
private TimeValue waitForCompletionTimeout = null;
|
private TimeValue waitForCompletionTimeout = null;
|
||||||
|
@ -67,7 +66,6 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
static final String KEY_WAIT_FOR_COMPLETION_TIMEOUT = "wait_for_completion_timeout";
|
static final String KEY_WAIT_FOR_COMPLETION_TIMEOUT = "wait_for_completion_timeout";
|
||||||
static final String KEY_KEEP_ALIVE = "keep_alive";
|
static final String KEY_KEEP_ALIVE = "keep_alive";
|
||||||
static final String KEY_KEEP_ON_COMPLETION = "keep_on_completion";
|
static final String KEY_KEEP_ON_COMPLETION = "keep_on_completion";
|
||||||
static final String KEY_CASE_SENSITIVE = "case_sensitive";
|
|
||||||
|
|
||||||
static final ParseField FILTER = new ParseField(KEY_FILTER);
|
static final ParseField FILTER = new ParseField(KEY_FILTER);
|
||||||
static final ParseField TIMESTAMP_FIELD = new ParseField(KEY_TIMESTAMP_FIELD);
|
static final ParseField TIMESTAMP_FIELD = new ParseField(KEY_TIMESTAMP_FIELD);
|
||||||
|
@ -79,7 +77,6 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
static final ParseField WAIT_FOR_COMPLETION_TIMEOUT = new ParseField(KEY_WAIT_FOR_COMPLETION_TIMEOUT);
|
static final ParseField WAIT_FOR_COMPLETION_TIMEOUT = new ParseField(KEY_WAIT_FOR_COMPLETION_TIMEOUT);
|
||||||
static final ParseField KEEP_ALIVE = new ParseField(KEY_KEEP_ALIVE);
|
static final ParseField KEEP_ALIVE = new ParseField(KEY_KEEP_ALIVE);
|
||||||
static final ParseField KEEP_ON_COMPLETION = new ParseField(KEY_KEEP_ON_COMPLETION);
|
static final ParseField KEEP_ON_COMPLETION = new ParseField(KEY_KEEP_ON_COMPLETION);
|
||||||
static final ParseField CASE_SENSITIVE = new ParseField(KEY_CASE_SENSITIVE);
|
|
||||||
|
|
||||||
private static final ObjectParser<EqlSearchRequest, Void> PARSER = objectParser(EqlSearchRequest::new);
|
private static final ObjectParser<EqlSearchRequest, Void> PARSER = objectParser(EqlSearchRequest::new);
|
||||||
|
|
||||||
|
@ -103,7 +100,9 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
this.keepAlive = in.readOptionalTimeValue();
|
this.keepAlive = in.readOptionalTimeValue();
|
||||||
this.keepOnCompletion = in.readBoolean();
|
this.keepOnCompletion = in.readBoolean();
|
||||||
}
|
}
|
||||||
isCaseSensitive = in.readBoolean();
|
if (in.getVersion().before(Version.V_7_10_0)) {
|
||||||
|
in.readBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -178,7 +177,6 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
builder.field(KEY_KEEP_ALIVE, keepAlive);
|
builder.field(KEY_KEEP_ALIVE, keepAlive);
|
||||||
}
|
}
|
||||||
builder.field(KEY_KEEP_ON_COMPLETION, keepOnCompletion);
|
builder.field(KEY_KEEP_ON_COMPLETION, keepOnCompletion);
|
||||||
builder.field(KEY_CASE_SENSITIVE, isCaseSensitive);
|
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +201,6 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
parser.declareField(EqlSearchRequest::keepAlive,
|
parser.declareField(EqlSearchRequest::keepAlive,
|
||||||
(p, c) -> TimeValue.parseTimeValue(p.text(), KEY_KEEP_ALIVE), KEEP_ALIVE, ObjectParser.ValueType.VALUE);
|
(p, c) -> TimeValue.parseTimeValue(p.text(), KEY_KEEP_ALIVE), KEEP_ALIVE, ObjectParser.ValueType.VALUE);
|
||||||
parser.declareBoolean(EqlSearchRequest::keepOnCompletion, KEEP_ON_COMPLETION);
|
parser.declareBoolean(EqlSearchRequest::keepOnCompletion, KEEP_ON_COMPLETION);
|
||||||
parser.declareBoolean(EqlSearchRequest::isCaseSensitive, CASE_SENSITIVE);
|
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,13 +290,6 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCaseSensitive() { return this.isCaseSensitive; }
|
|
||||||
|
|
||||||
public EqlSearchRequest isCaseSensitive(boolean isCaseSensitive) {
|
|
||||||
this.isCaseSensitive = isCaseSensitive;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
super.writeTo(out);
|
super.writeTo(out);
|
||||||
|
@ -317,7 +307,9 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
out.writeOptionalTimeValue(keepAlive);
|
out.writeOptionalTimeValue(keepAlive);
|
||||||
out.writeBoolean(keepOnCompletion);
|
out.writeBoolean(keepOnCompletion);
|
||||||
}
|
}
|
||||||
out.writeBoolean(isCaseSensitive);
|
if (out.getVersion().onOrAfter(Version.V_7_10_0)) {
|
||||||
|
out.writeBoolean(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -341,8 +333,7 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
Objects.equals(eventCategoryField, that.eventCategoryField) &&
|
Objects.equals(eventCategoryField, that.eventCategoryField) &&
|
||||||
Objects.equals(query, that.query) &&
|
Objects.equals(query, that.query) &&
|
||||||
Objects.equals(waitForCompletionTimeout, that.waitForCompletionTimeout) &&
|
Objects.equals(waitForCompletionTimeout, that.waitForCompletionTimeout) &&
|
||||||
Objects.equals(keepAlive, that.keepAlive) &&
|
Objects.equals(keepAlive, that.keepAlive);
|
||||||
Objects.equals(isCaseSensitive, that.isCaseSensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,8 +350,7 @@ public class EqlSearchRequest extends ActionRequest implements IndicesRequest.Re
|
||||||
eventCategoryField,
|
eventCategoryField,
|
||||||
query,
|
query,
|
||||||
waitForCompletionTimeout,
|
waitForCompletionTimeout,
|
||||||
keepAlive,
|
keepAlive);
|
||||||
isCaseSensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -54,9 +54,4 @@ public class EqlSearchRequestBuilder extends ActionRequestBuilder<EqlSearchReque
|
||||||
request.query(query);
|
request.query(query);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EqlSearchRequestBuilder isCaseSensitive(boolean isCaseSensitive) {
|
|
||||||
request.isCaseSensitive(isCaseSensitive);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class EqlFunctionRegistry extends FunctionRegistry {
|
||||||
// Scalar functions
|
// Scalar functions
|
||||||
// String
|
// String
|
||||||
new FunctionDefinition[] {
|
new FunctionDefinition[] {
|
||||||
def(Between.class, Between::new, 2, "between"),
|
def(Between.class, Between::new, "between"),
|
||||||
def(CIDRMatch.class, CIDRMatch::new, "cidrmatch"),
|
def(CIDRMatch.class, CIDRMatch::new, "cidrmatch"),
|
||||||
def(Concat.class, Concat::new, "concat"),
|
def(Concat.class, Concat::new, "concat"),
|
||||||
def(EndsWith.class, EndsWith::new, "endswith"),
|
def(EndsWith.class, EndsWith::new, "endswith"),
|
||||||
|
|
|
@ -32,20 +32,20 @@ import static org.elasticsearch.xpack.ql.expression.gen.script.ParamsBuilder.par
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EQL specific between function.
|
* EQL specific between function.
|
||||||
* between(source, left, right[, greedy=false, case_sensitive=false])
|
* between(source, left, right[, greedy=false])
|
||||||
* Extracts a substring from source that’s between left and right substrings
|
* Extracts a substring from source that’s between left and right substrings
|
||||||
*/
|
*/
|
||||||
public class Between extends ScalarFunction implements OptionalArgument {
|
public class Between extends ScalarFunction implements OptionalArgument {
|
||||||
|
|
||||||
private final Expression input, left, right, greedy, caseSensitive;
|
private final Expression input, left, right, greedy, caseSensitive;
|
||||||
|
|
||||||
public Between(Source source, Expression input, Expression left, Expression right, Expression greedy, Expression caseSensitive) {
|
public Between(Source source, Expression input, Expression left, Expression right, Expression greedy) {
|
||||||
super(source, Arrays.asList(input, left, right, toDefault(greedy), toDefault(caseSensitive)));
|
super(source, Arrays.asList(input, left, right, toDefault(greedy)));
|
||||||
this.input = input;
|
this.input = input;
|
||||||
this.left = left;
|
this.left = left;
|
||||||
this.right = right;
|
this.right = right;
|
||||||
this.greedy = arguments().get(3);
|
this.greedy = arguments().get(3);
|
||||||
this.caseSensitive = arguments().get(4);
|
this.caseSensitive = Literal.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Expression toDefault(Expression exp) {
|
private static Expression toDefault(Expression exp) {
|
||||||
|
@ -73,12 +73,12 @@ public class Between extends ScalarFunction implements OptionalArgument {
|
||||||
return resolution;
|
return resolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolution = isBoolean(greedy, sourceText(), Expressions.ParamOrdinal.FOURTH);
|
return isBoolean(greedy, sourceText(), Expressions.ParamOrdinal.FOURTH);
|
||||||
if (resolution.unresolved()) {
|
// if (resolution.unresolved()) {
|
||||||
return resolution;
|
// return resolution;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return isBoolean(caseSensitive, sourceText(), Expressions.ParamOrdinal.FIFTH);
|
// return isBoolean(caseSensitive, sourceText(), Expressions.ParamOrdinal.FIFTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -100,7 +100,7 @@ public class Between extends ScalarFunction implements OptionalArgument {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NodeInfo<? extends Expression> info() {
|
protected NodeInfo<? extends Expression> info() {
|
||||||
return NodeInfo.create(this, Between::new, input, left, right, greedy, caseSensitive);
|
return NodeInfo.create(this, Between::new, input, left, right, greedy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,10 +146,10 @@ public class Between extends ScalarFunction implements OptionalArgument {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expression replaceChildren(List<Expression> newChildren) {
|
public Expression replaceChildren(List<Expression> newChildren) {
|
||||||
if (newChildren.size() != 5) {
|
if (newChildren.size() != 4) {
|
||||||
throw new IllegalArgumentException("expected [5] children but received [" + newChildren.size() + "]");
|
throw new IllegalArgumentException("expected [4] children but received [" + newChildren.size() + "]");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Between(source(), newChildren.get(0), newChildren.get(1), newChildren.get(2), newChildren.get(3), newChildren.get(4));
|
return new Between(source(), newChildren.get(0), newChildren.get(1), newChildren.get(2), newChildren.get(3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.xpack.eql.expression.function.scalar.string;
|
package org.elasticsearch.xpack.eql.expression.function.scalar.string;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.eql.session.EqlConfiguration;
|
|
||||||
import org.elasticsearch.xpack.ql.expression.Expression;
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expressions;
|
import org.elasticsearch.xpack.ql.expression.Expressions;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal;
|
import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal;
|
||||||
|
@ -47,7 +46,7 @@ public class EndsWith extends CaseSensitiveScalarFunction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaseSensitive() {
|
public boolean isCaseSensitive() {
|
||||||
return ((EqlConfiguration) configuration()).isCaseSensitive();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.xpack.eql.expression.function.scalar.string;
|
package org.elasticsearch.xpack.eql.expression.function.scalar.string;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.eql.session.EqlConfiguration;
|
|
||||||
import org.elasticsearch.xpack.ql.expression.Expression;
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expressions;
|
import org.elasticsearch.xpack.ql.expression.Expressions;
|
||||||
import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal;
|
import org.elasticsearch.xpack.ql.expression.Expressions.ParamOrdinal;
|
||||||
|
@ -50,7 +49,7 @@ public class IndexOf extends CaseSensitiveScalarFunction implements OptionalArgu
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaseSensitive() {
|
public boolean isCaseSensitive() {
|
||||||
return ((EqlConfiguration) configuration()).isCaseSensitive();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
package org.elasticsearch.xpack.eql.expression.function.scalar.string;
|
package org.elasticsearch.xpack.eql.expression.function.scalar.string;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.eql.session.EqlConfiguration;
|
|
||||||
import org.elasticsearch.xpack.ql.expression.Expression;
|
import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.session.Configuration;
|
import org.elasticsearch.xpack.ql.session.Configuration;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
|
@ -19,7 +18,7 @@ public class StartsWith extends org.elasticsearch.xpack.ql.expression.function.s
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaseSensitive() {
|
public boolean isCaseSensitive() {
|
||||||
return ((EqlConfiguration) configuration()).isCaseSensitive();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,6 +132,6 @@ public class StringContains extends CaseSensitiveScalarFunction {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCaseSensitive() {
|
public boolean isCaseSensitive() {
|
||||||
return eqlConfiguration().isCaseSensitive();
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,7 +131,7 @@ public class Optimizer extends RuleExecutor<LogicalPlan> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
Expression like = new Like(e.source(), target, StringUtils.toLikePattern(wildString));
|
Expression like = new Like(e.source(), target, StringUtils.toLikePattern(wildString), true);
|
||||||
if (e instanceof InsensitiveNotEquals) {
|
if (e instanceof InsensitiveNotEquals) {
|
||||||
like = new Not(e.source(), like);
|
like = new Not(e.source(), like);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ final class QueryTranslator {
|
||||||
// (which is important for strings)
|
// (which is important for strings)
|
||||||
name = ((FieldAttribute) bc.left()).exactAttribute().name();
|
name = ((FieldAttribute) bc.left()).exactAttribute().name();
|
||||||
}
|
}
|
||||||
Query query = new TermQuery(source, name, value);
|
Query query = new TermQuery(source, name, value, true);
|
||||||
|
|
||||||
if (bc instanceof InsensitiveNotEquals) {
|
if (bc instanceof InsensitiveNotEquals) {
|
||||||
query = new NotQuery(source, query);
|
query = new NotQuery(source, query);
|
||||||
|
|
|
@ -119,7 +119,7 @@ public class TransportEqlSearchAction extends HandledTransportAction<EqlSearchRe
|
||||||
.fetchSize(request.fetchSize());
|
.fetchSize(request.fetchSize());
|
||||||
|
|
||||||
EqlConfiguration cfg = new EqlConfiguration(request.indices(), zoneId, username, clusterName, filter, timeout, includeFrozen,
|
EqlConfiguration cfg = new EqlConfiguration(request.indices(), zoneId, username, clusterName, filter, timeout, includeFrozen,
|
||||||
request.isCaseSensitive(), request.fetchSize(), clientId, new TaskId(nodeId, task.getId()), task);
|
request.fetchSize(), clientId, new TaskId(nodeId, task.getId()), task);
|
||||||
planExecutor.eql(cfg, request.query(), params, wrap(r -> listener.onResponse(createResponse(r, task.getExecutionId())),
|
planExecutor.eql(cfg, request.query(), params, wrap(r -> listener.onResponse(createResponse(r, task.getExecutionId())),
|
||||||
listener::onFailure));
|
listener::onFailure));
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,14 +23,13 @@ public class EqlConfiguration extends org.elasticsearch.xpack.ql.session.Configu
|
||||||
private final boolean includeFrozenIndices;
|
private final boolean includeFrozenIndices;
|
||||||
private final TaskId taskId;
|
private final TaskId taskId;
|
||||||
private final EqlSearchTask task;
|
private final EqlSearchTask task;
|
||||||
private final boolean isCaseSensitive;
|
|
||||||
private final int fetchSize;
|
private final int fetchSize;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final QueryBuilder filter;
|
private final QueryBuilder filter;
|
||||||
|
|
||||||
public EqlConfiguration(String[] indices, ZoneId zi, String username, String clusterName, QueryBuilder filter, TimeValue requestTimeout,
|
public EqlConfiguration(String[] indices, ZoneId zi, String username, String clusterName, QueryBuilder filter, TimeValue requestTimeout,
|
||||||
boolean includeFrozen, boolean isCaseSensitive, int fetchSize, String clientId, TaskId taskId,
|
boolean includeFrozen, int fetchSize, String clientId, TaskId taskId,
|
||||||
EqlSearchTask task) {
|
EqlSearchTask task) {
|
||||||
super(zi, username, clusterName);
|
super(zi, username, clusterName);
|
||||||
|
|
||||||
|
@ -39,7 +38,6 @@ public class EqlConfiguration extends org.elasticsearch.xpack.ql.session.Configu
|
||||||
this.requestTimeout = requestTimeout;
|
this.requestTimeout = requestTimeout;
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.includeFrozenIndices = includeFrozen;
|
this.includeFrozenIndices = includeFrozen;
|
||||||
this.isCaseSensitive = isCaseSensitive;
|
|
||||||
this.taskId = taskId;
|
this.taskId = taskId;
|
||||||
this.task = task;
|
this.task = task;
|
||||||
this.fetchSize = fetchSize;
|
this.fetchSize = fetchSize;
|
||||||
|
@ -73,10 +71,6 @@ public class EqlConfiguration extends org.elasticsearch.xpack.ql.session.Configu
|
||||||
return includeFrozenIndices;
|
return includeFrozenIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isCaseSensitive() {
|
|
||||||
return isCaseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return task.isCancelled();
|
return task.isCancelled();
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,23 +31,11 @@ public final class EqlTestUtils {
|
||||||
private EqlTestUtils() {
|
private EqlTestUtils() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final EqlConfiguration TEST_CFG_CASE_INSENSITIVE = new EqlConfiguration(new String[] {"none"},
|
public static final EqlConfiguration TEST_CFG = new EqlConfiguration(new String[] {"none"},
|
||||||
org.elasticsearch.xpack.ql.util.DateUtils.UTC, "nobody", "cluster", null, TimeValue.timeValueSeconds(30), false, false,
|
org.elasticsearch.xpack.ql.util.DateUtils.UTC, "nobody", "cluster", null, TimeValue.timeValueSeconds(30), false,
|
||||||
123, "", new TaskId("test", 123), null);
|
|
||||||
|
|
||||||
public static final EqlConfiguration TEST_CFG_CASE_SENSITIVE = new EqlConfiguration(new String[] {"none"},
|
|
||||||
org.elasticsearch.xpack.ql.util.DateUtils.UTC, "nobody", "cluster", null, TimeValue.timeValueSeconds(30), false, true,
|
|
||||||
123, "", new TaskId("test", 123), null);
|
123, "", new TaskId("test", 123), null);
|
||||||
|
|
||||||
public static EqlConfiguration randomConfiguration() {
|
public static EqlConfiguration randomConfiguration() {
|
||||||
return internalRandomConfiguration(randomBoolean());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EqlConfiguration randomConfigurationWithCaseSensitive(boolean isCaseSensitive) {
|
|
||||||
return internalRandomConfiguration(isCaseSensitive);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static EqlConfiguration internalRandomConfiguration(boolean isCaseSensitive) {
|
|
||||||
return new EqlConfiguration(new String[]{randomAlphaOfLength(16)},
|
return new EqlConfiguration(new String[]{randomAlphaOfLength(16)},
|
||||||
randomZone(),
|
randomZone(),
|
||||||
randomAlphaOfLength(16),
|
randomAlphaOfLength(16),
|
||||||
|
@ -55,7 +43,6 @@ public final class EqlTestUtils {
|
||||||
null,
|
null,
|
||||||
new TimeValue(randomNonNegativeLong()),
|
new TimeValue(randomNonNegativeLong()),
|
||||||
randomBoolean(),
|
randomBoolean(),
|
||||||
isCaseSensitive,
|
|
||||||
randomIntBetween(1, 1000),
|
randomIntBetween(1, 1000),
|
||||||
randomAlphaOfLength(16),
|
randomAlphaOfLength(16),
|
||||||
new TaskId(randomAlphaOfLength(10), randomNonNegativeLong()),
|
new TaskId(randomAlphaOfLength(10), randomNonNegativeLong()),
|
||||||
|
|
|
@ -42,18 +42,13 @@ public class EqlRequestParserTests extends ESTestCase {
|
||||||
EqlSearchRequest::fromXContent);
|
EqlSearchRequest::fromXContent);
|
||||||
assertParsingErrorMessage("{\"query\" : \"whatever\", \"size\":\"abc\"}", "failed to parse field [size]",
|
assertParsingErrorMessage("{\"query\" : \"whatever\", \"size\":\"abc\"}", "failed to parse field [size]",
|
||||||
EqlSearchRequest::fromXContent);
|
EqlSearchRequest::fromXContent);
|
||||||
assertParsingErrorMessage("{\"case_sensitive\" : \"whatever\"}", "failed to parse field [case_sensitive]",
|
|
||||||
EqlSearchRequest::fromXContent);
|
|
||||||
|
|
||||||
boolean setIsCaseSensitive = randomBoolean();
|
|
||||||
boolean isCaseSensitive = randomBoolean();
|
|
||||||
EqlSearchRequest request = generateRequest("endgame-*", "{\"filter\" : {\"match\" : {\"foo\":\"bar\"}}, "
|
EqlSearchRequest request = generateRequest("endgame-*", "{\"filter\" : {\"match\" : {\"foo\":\"bar\"}}, "
|
||||||
+ "\"timestamp_field\" : \"tsf\", "
|
+ "\"timestamp_field\" : \"tsf\", "
|
||||||
+ "\"event_category_field\" : \"etf\","
|
+ "\"event_category_field\" : \"etf\","
|
||||||
+ "\"size\" : \"101\","
|
+ "\"size\" : \"101\","
|
||||||
+ "\"query\" : \"file where user != 'SYSTEM' by file_path\""
|
+ "\"query\" : \"file where user != 'SYSTEM' by file_path\"}"
|
||||||
+ (setIsCaseSensitive ? (",\"case_sensitive\" : " + isCaseSensitive) : "")
|
, EqlSearchRequest::fromXContent);
|
||||||
+ "}", EqlSearchRequest::fromXContent);
|
|
||||||
assertArrayEquals(new String[]{"endgame-*"}, request.indices());
|
assertArrayEquals(new String[]{"endgame-*"}, request.indices());
|
||||||
assertNotNull(request.query());
|
assertNotNull(request.query());
|
||||||
assertTrue(request.filter() instanceof MatchQueryBuilder);
|
assertTrue(request.filter() instanceof MatchQueryBuilder);
|
||||||
|
@ -65,7 +60,6 @@ public class EqlRequestParserTests extends ESTestCase {
|
||||||
assertEquals(101, request.size());
|
assertEquals(101, request.size());
|
||||||
assertEquals(1000, request.fetchSize());
|
assertEquals(1000, request.fetchSize());
|
||||||
assertEquals("file where user != 'SYSTEM' by file_path", request.query());
|
assertEquals("file where user != 'SYSTEM' by file_path", request.query());
|
||||||
assertEquals(setIsCaseSensitive && isCaseSensitive, request.isCaseSensitive());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private EqlSearchRequest generateRequest(String index, String json, Function<XContentParser, EqlSearchRequest> fromXContent)
|
private EqlSearchRequest generateRequest(String index, String json, Function<XContentParser, EqlSearchRequest> fromXContent)
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class VerifierTests extends ESTestCase {
|
||||||
|
|
||||||
private LogicalPlan accept(IndexResolution resolution, String eql) {
|
private LogicalPlan accept(IndexResolution resolution, String eql) {
|
||||||
PreAnalyzer preAnalyzer = new PreAnalyzer();
|
PreAnalyzer preAnalyzer = new PreAnalyzer();
|
||||||
Analyzer analyzer = new Analyzer(EqlTestUtils.TEST_CFG_CASE_INSENSITIVE, new EqlFunctionRegistry(), new Verifier(new Metrics()));
|
Analyzer analyzer = new Analyzer(EqlTestUtils.TEST_CFG, new EqlFunctionRegistry(), new Verifier(new Metrics()));
|
||||||
return analyzer.analyze(preAnalyzer.preAnalyze(parser.createStatement(eql), resolution));
|
return analyzer.analyze(preAnalyzer.preAnalyze(parser.createStatement(eql), resolution));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,7 @@ public class BetweenFunctionPipeTests extends AbstractNodeTestCase<BetweenFuncti
|
||||||
randomStringLiteral(),
|
randomStringLiteral(),
|
||||||
randomStringLiteral(),
|
randomStringLiteral(),
|
||||||
randomStringLiteral(),
|
randomStringLiteral(),
|
||||||
randomFrom(true, false) ? randomBooleanLiteral() : null,
|
randomFrom(true, false) ? randomBooleanLiteral() : null)
|
||||||
randomBooleanLiteral())
|
|
||||||
.makePipe());
|
.makePipe());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,9 @@ import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
|
||||||
import org.elasticsearch.xpack.ql.expression.Literal;
|
import org.elasticsearch.xpack.ql.expression.Literal;
|
||||||
import org.elasticsearch.xpack.ql.expression.LiteralTests;
|
import org.elasticsearch.xpack.ql.expression.LiteralTests;
|
||||||
import org.elasticsearch.xpack.ql.session.Configuration;
|
import org.elasticsearch.xpack.ql.session.Configuration;
|
||||||
|
import org.junit.Assume;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.eql.EqlTestUtils.randomConfigurationWithCaseSensitive;
|
import static org.elasticsearch.xpack.eql.EqlTestUtils.randomConfiguration;
|
||||||
import static org.elasticsearch.xpack.ql.expression.function.scalar.FunctionTestUtils.l;
|
import static org.elasticsearch.xpack.ql.expression.function.scalar.FunctionTestUtils.l;
|
||||||
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
||||||
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
|
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
|
||||||
|
@ -20,10 +21,8 @@ import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
public class EndsWithFunctionProcessorTests extends ESTestCase {
|
public class EndsWithFunctionProcessorTests extends ESTestCase {
|
||||||
|
|
||||||
final Configuration caseInsensitive = randomConfigurationWithCaseSensitive(false);
|
|
||||||
|
|
||||||
public void testEndsWithFunctionWithValidInputCaseSensitive() {
|
public void testEndsWithFunctionWithValidInputCaseSensitive() {
|
||||||
final Configuration caseSensitive = randomConfigurationWithCaseSensitive(true);
|
final Configuration caseSensitive = randomConfiguration();
|
||||||
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("r"), caseSensitive).makePipe().asProcessor().process(null));
|
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("r"), caseSensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(false, new EndsWith(EMPTY, l("foobarbar"), l("R"), caseSensitive).makePipe().asProcessor().process(null));
|
assertEquals(false, new EndsWith(EMPTY, l("foobarbar"), l("R"), caseSensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("bar"), caseSensitive).makePipe().asProcessor().process(null));
|
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("bar"), caseSensitive).makePipe().asProcessor().process(null));
|
||||||
|
@ -42,6 +41,9 @@ public class EndsWithFunctionProcessorTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEndsWithFunctionWithValidInputCaseInsensitive() {
|
public void testEndsWithFunctionWithValidInputCaseInsensitive() {
|
||||||
|
Assume.assumeTrue(false); //TODO: revisit after we decide on functions case sensitivity handling
|
||||||
|
|
||||||
|
final Configuration caseInsensitive = randomConfiguration();
|
||||||
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("r"), caseInsensitive).makePipe().asProcessor().process(null));
|
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("r"), caseInsensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("R"), caseInsensitive).makePipe().asProcessor().process(null));
|
assertEquals(true, new EndsWith(EMPTY, l("foobarbar"), l("R"), caseInsensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(false, new EndsWith(EMPTY, l("foobar"), l("foo"), caseInsensitive).makePipe().asProcessor().process(null));
|
assertEquals(false, new EndsWith(EMPTY, l("foobar"), l("foo"), caseInsensitive).makePipe().asProcessor().process(null));
|
||||||
|
@ -58,21 +60,23 @@ public class EndsWithFunctionProcessorTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEndsWithFunctionInputsValidation() {
|
public void testEndsWithFunctionInputsValidation() {
|
||||||
|
Configuration config = randomConfiguration();
|
||||||
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new EndsWith(EMPTY, l(5), l("foo"), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new EndsWith(EMPTY, l(5), l("foo"), config).makePipe().asProcessor().process(null));
|
||||||
assertEquals("A string/char is required; received [5]", siae.getMessage());
|
assertEquals("A string/char is required; received [5]", siae.getMessage());
|
||||||
siae = expectThrows(QlIllegalArgumentException.class,
|
siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new EndsWith(EMPTY, l("bar"), l(false), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new EndsWith(EMPTY, l("bar"), l(false), config).makePipe().asProcessor().process(null));
|
||||||
assertEquals("A string/char is required; received [false]", siae.getMessage());
|
assertEquals("A string/char is required; received [false]", siae.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEndsWithFunctionWithRandomInvalidDataType() {
|
public void testEndsWithFunctionWithRandomInvalidDataType() {
|
||||||
|
Configuration config = randomConfiguration();
|
||||||
Literal literal = randomValueOtherThanMany(v -> v.dataType() == KEYWORD, () -> LiteralTests.randomLiteral());
|
Literal literal = randomValueOtherThanMany(v -> v.dataType() == KEYWORD, () -> LiteralTests.randomLiteral());
|
||||||
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new EndsWith(EMPTY, literal, l("foo"), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new EndsWith(EMPTY, literal, l("foo"), config).makePipe().asProcessor().process(null));
|
||||||
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
||||||
siae = expectThrows(QlIllegalArgumentException.class,
|
siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new EndsWith(EMPTY, l("foo"), literal, caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new EndsWith(EMPTY, l("foo"), literal, config).makePipe().asProcessor().process(null));
|
||||||
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,9 @@ import org.elasticsearch.xpack.ql.QlIllegalArgumentException;
|
||||||
import org.elasticsearch.xpack.ql.expression.Literal;
|
import org.elasticsearch.xpack.ql.expression.Literal;
|
||||||
import org.elasticsearch.xpack.ql.expression.LiteralTests;
|
import org.elasticsearch.xpack.ql.expression.LiteralTests;
|
||||||
import org.elasticsearch.xpack.ql.session.Configuration;
|
import org.elasticsearch.xpack.ql.session.Configuration;
|
||||||
|
import org.junit.Assume;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.eql.EqlTestUtils.randomConfigurationWithCaseSensitive;
|
import static org.elasticsearch.xpack.eql.EqlTestUtils.randomConfiguration;
|
||||||
import static org.elasticsearch.xpack.ql.expression.function.scalar.FunctionTestUtils.l;
|
import static org.elasticsearch.xpack.ql.expression.function.scalar.FunctionTestUtils.l;
|
||||||
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
||||||
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
|
import static org.elasticsearch.xpack.ql.type.DataTypes.KEYWORD;
|
||||||
|
@ -20,9 +21,10 @@ import static org.hamcrest.Matchers.startsWith;
|
||||||
|
|
||||||
public class IndexOfFunctionProcessorTests extends ESTestCase {
|
public class IndexOfFunctionProcessorTests extends ESTestCase {
|
||||||
|
|
||||||
final Configuration caseInsensitive = randomConfigurationWithCaseSensitive(false);
|
|
||||||
|
|
||||||
public void testIndexOfFunctionWithValidInputInsensitive() {
|
public void testIndexOfFunctionWithValidInputInsensitive() {
|
||||||
|
Assume.assumeTrue(false); //TODO: revisit after we decide on functions case sensitivity handling
|
||||||
|
|
||||||
|
final Configuration caseInsensitive = randomConfiguration();
|
||||||
assertEquals(5, new IndexOf(EMPTY, l("foobarbar"), l("r"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
assertEquals(5, new IndexOf(EMPTY, l("foobarbar"), l("r"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(5, new IndexOf(EMPTY, l("foobaRbar"), l("r"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
assertEquals(5, new IndexOf(EMPTY, l("foobaRbar"), l("r"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(0, new IndexOf(EMPTY, l("foobar"), l("Foo"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
assertEquals(0, new IndexOf(EMPTY, l("foobar"), l("Foo"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
||||||
|
@ -44,7 +46,7 @@ public class IndexOfFunctionProcessorTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIndexOfFunctionWithValidInputSensitive() {
|
public void testIndexOfFunctionWithValidInputSensitive() {
|
||||||
final Configuration caseSensitive = randomConfigurationWithCaseSensitive(true);
|
final Configuration caseSensitive = randomConfiguration();
|
||||||
assertEquals(5, new IndexOf(EMPTY, l("foobarbar"), l("r"), l(null), caseSensitive).makePipe().asProcessor().process(null));
|
assertEquals(5, new IndexOf(EMPTY, l("foobarbar"), l("r"), l(null), caseSensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(8, new IndexOf(EMPTY, l("foobaRbar"), l("r"), l(null), caseSensitive).makePipe().asProcessor().process(null));
|
assertEquals(8, new IndexOf(EMPTY, l("foobaRbar"), l("r"), l(null), caseSensitive).makePipe().asProcessor().process(null));
|
||||||
assertEquals(4, new IndexOf(EMPTY, l("foobARbar"), l("AR"), l(null), caseSensitive).makePipe().asProcessor().process(null));
|
assertEquals(4, new IndexOf(EMPTY, l("foobARbar"), l("AR"), l(null), caseSensitive).makePipe().asProcessor().process(null));
|
||||||
|
@ -67,30 +69,32 @@ public class IndexOfFunctionProcessorTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIndexOfFunctionInputsValidation() {
|
public void testIndexOfFunctionInputsValidation() {
|
||||||
|
Configuration config = randomConfiguration();
|
||||||
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new IndexOf(EMPTY, l(5), l("foo"), l(null), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new IndexOf(EMPTY, l(5), l("foo"), l(null), config).makePipe().asProcessor().process(null));
|
||||||
assertEquals("A string/char is required; received [5]", siae.getMessage());
|
assertEquals("A string/char is required; received [5]", siae.getMessage());
|
||||||
siae = expectThrows(QlIllegalArgumentException.class,
|
siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new IndexOf(EMPTY, l("bar"), l(false), l(2), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new IndexOf(EMPTY, l("bar"), l(false), l(2), config).makePipe().asProcessor().process(null));
|
||||||
assertEquals("A string/char is required; received [false]", siae.getMessage());
|
assertEquals("A string/char is required; received [false]", siae.getMessage());
|
||||||
siae = expectThrows(QlIllegalArgumentException.class,
|
siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new IndexOf(EMPTY, l("bar"), l("a"), l("1"), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new IndexOf(EMPTY, l("bar"), l("a"), l("1"), config).makePipe().asProcessor().process(null));
|
||||||
assertEquals("A number is required; received [1]", siae.getMessage());
|
assertEquals("A number is required; received [1]", siae.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testIndexOfFunctionWithRandomInvalidDataType() {
|
public void testIndexOfFunctionWithRandomInvalidDataType() {
|
||||||
|
Configuration config = randomConfiguration();
|
||||||
Literal stringLiteral = randomValueOtherThanMany(v -> v.dataType() == KEYWORD, () -> LiteralTests.randomLiteral());
|
Literal stringLiteral = randomValueOtherThanMany(v -> v.dataType() == KEYWORD, () -> LiteralTests.randomLiteral());
|
||||||
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
QlIllegalArgumentException siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new IndexOf(EMPTY, stringLiteral, l("foo"), l(1), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new IndexOf(EMPTY, stringLiteral, l("foo"), l(1), config).makePipe().asProcessor().process(null));
|
||||||
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
||||||
|
|
||||||
siae = expectThrows(QlIllegalArgumentException.class,
|
siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new IndexOf(EMPTY, l("foo"), stringLiteral, l(2), caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new IndexOf(EMPTY, l("foo"), stringLiteral, l(2), config).makePipe().asProcessor().process(null));
|
||||||
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
assertThat(siae.getMessage(), startsWith("A string/char is required; received"));
|
||||||
|
|
||||||
Literal numericLiteral = randomValueOtherThanMany(v -> v.dataType().isNumeric(), () -> LiteralTests.randomLiteral());
|
Literal numericLiteral = randomValueOtherThanMany(v -> v.dataType().isNumeric(), () -> LiteralTests.randomLiteral());
|
||||||
siae = expectThrows(QlIllegalArgumentException.class,
|
siae = expectThrows(QlIllegalArgumentException.class,
|
||||||
() -> new IndexOf(EMPTY, l("foo"), l("o"), numericLiteral, caseInsensitive).makePipe().asProcessor().process(null));
|
() -> new IndexOf(EMPTY, l("foo"), l("o"), numericLiteral, config).makePipe().asProcessor().process(null));
|
||||||
assertThat(siae.getMessage(), startsWith("A number is required; received"));
|
assertThat(siae.getMessage(), startsWith("A number is required; received"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,18 +13,18 @@ import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.eql.EqlTestUtils.randomConfigurationWithCaseSensitive;
|
import static org.elasticsearch.xpack.eql.EqlTestUtils.randomConfiguration;
|
||||||
|
|
||||||
public class StartsWithFunctionProcessorTests extends org.elasticsearch.xpack.ql.expression.function.scalar.string.StartsWithProcessorTests{
|
public class StartsWithFunctionProcessorTests extends org.elasticsearch.xpack.ql.expression.function.scalar.string.StartsWithProcessorTests{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<Boolean> isCaseSensitiveGenerator() {
|
protected Supplier<Boolean> isCaseSensitiveGenerator() {
|
||||||
return () -> randomBoolean();
|
return () -> Boolean.TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<Configuration> configurationGenerator() {
|
protected Supplier<Configuration> configurationGenerator() {
|
||||||
return () -> randomConfigurationWithCaseSensitive(isCaseSensitive);
|
return () -> randomConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,16 +16,10 @@ public class EqlFoldSpec {
|
||||||
private final String description;
|
private final String description;
|
||||||
private final String expression;
|
private final String expression;
|
||||||
private final Object expected;
|
private final Object expected;
|
||||||
// flag to dictate which modes are supported for the test
|
|
||||||
// null -> apply the test to both modes (case sensitive and case insensitive)
|
|
||||||
// TRUE -> case sensitive
|
|
||||||
// FALSE -> case insensitive
|
|
||||||
private Boolean caseSensitive = null;
|
|
||||||
|
|
||||||
EqlFoldSpec(String name, String description, Boolean caseSensitive, String expression, Object expected) {
|
EqlFoldSpec(String name, String description, String expression, Object expected) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.caseSensitive = caseSensitive;
|
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
this.expected = expected;
|
this.expected = expected;
|
||||||
}
|
}
|
||||||
|
@ -38,15 +32,10 @@ public class EqlFoldSpec {
|
||||||
return expected;
|
return expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean caseSensitive() {
|
|
||||||
return caseSensitive;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
appendWithComma(sb, "name", name);
|
appendWithComma(sb, "name", name);
|
||||||
appendWithComma(sb, "expression", expression);
|
appendWithComma(sb, "expression", expression);
|
||||||
appendWithComma(sb, "case_sensitive", caseSensitive == null ? "null" : caseSensitive);
|
|
||||||
appendWithComma(sb, "expected", expected == null ? "null" : expected);
|
appendWithComma(sb, "expected", expected == null ? "null" : expected);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -78,12 +67,11 @@ public class EqlFoldSpec {
|
||||||
|
|
||||||
EqlFoldSpec that = (EqlFoldSpec) other;
|
EqlFoldSpec that = (EqlFoldSpec) other;
|
||||||
|
|
||||||
return Objects.equals(this.expression, that.expression)
|
return Objects.equals(this.expression, that.expression);
|
||||||
&& Objects.equals(this.caseSensitive, that.caseSensitive);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(this.expression, this.caseSensitive);
|
return Objects.hash(this.expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,20 +40,6 @@ public class EqlFoldSpecLoader {
|
||||||
TomlTable fold = table.getTomlTable("fold");
|
TomlTable fold = table.getTomlTable("fold");
|
||||||
|
|
||||||
String description = getTrimmedString(table, "description");
|
String description = getTrimmedString(table, "description");
|
||||||
Boolean cs = null;
|
|
||||||
Boolean caseSensitive = table.getBoolean("case_sensitive");
|
|
||||||
Boolean caseInsensitive = table.getBoolean("case_insensitive");
|
|
||||||
// if case_sensitive is TRUE and case_insensitive is not TRUE (FALSE or NULL), then the test is case sensitive only
|
|
||||||
if (Boolean.TRUE.equals(caseSensitive)) {
|
|
||||||
if (Boolean.FALSE.equals(caseInsensitive) || caseInsensitive == null) {
|
|
||||||
cs = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if case_sensitive is not TRUE (FALSE or NULL) and case_insensitive is TRUE, then the test is case insensitive only
|
|
||||||
else if (Boolean.TRUE.equals(caseInsensitive)) {
|
|
||||||
cs = false;
|
|
||||||
}
|
|
||||||
// in all other cases, the test should run no matter the case sensitivity (should test both scenarios)
|
|
||||||
|
|
||||||
if (fold != null) {
|
if (fold != null) {
|
||||||
List<TomlTable> tests = fold.getArrayTable("tests");
|
List<TomlTable> tests = fold.getArrayTable("tests");
|
||||||
|
@ -61,7 +47,7 @@ public class EqlFoldSpecLoader {
|
||||||
for (TomlTable test : tests) {
|
for (TomlTable test : tests) {
|
||||||
String expression = getTrimmedString(test, "expression");
|
String expression = getTrimmedString(test, "expression");
|
||||||
Object expected = test.get("expected");
|
Object expected = test.get("expected");
|
||||||
EqlFoldSpec spec = new EqlFoldSpec(name, description, cs, expression, expected);
|
EqlFoldSpec spec = new EqlFoldSpec(name, description, expression, expected);
|
||||||
testSpecs.add(spec);
|
testSpecs.add(spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.emptyMap;
|
import static java.util.Collections.emptyMap;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static org.elasticsearch.xpack.eql.EqlTestUtils.TEST_CFG_CASE_INSENSITIVE;
|
import static org.elasticsearch.xpack.eql.EqlTestUtils.TEST_CFG;
|
||||||
import static org.elasticsearch.xpack.ql.TestUtils.UTC;
|
import static org.elasticsearch.xpack.ql.TestUtils.UTC;
|
||||||
import static org.elasticsearch.xpack.ql.expression.Literal.TRUE;
|
import static org.elasticsearch.xpack.ql.expression.Literal.TRUE;
|
||||||
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
||||||
|
@ -84,9 +84,9 @@ public class OptimizerTests extends ESTestCase {
|
||||||
private LogicalPlan accept(IndexResolution resolution, String eql) {
|
private LogicalPlan accept(IndexResolution resolution, String eql) {
|
||||||
PreAnalyzer preAnalyzer = new PreAnalyzer();
|
PreAnalyzer preAnalyzer = new PreAnalyzer();
|
||||||
PostAnalyzer postAnalyzer = new PostAnalyzer();
|
PostAnalyzer postAnalyzer = new PostAnalyzer();
|
||||||
Analyzer analyzer = new Analyzer(TEST_CFG_CASE_INSENSITIVE, new EqlFunctionRegistry(), new Verifier(new Metrics()));
|
Analyzer analyzer = new Analyzer(TEST_CFG, new EqlFunctionRegistry(), new Verifier(new Metrics()));
|
||||||
return optimizer.optimize(postAnalyzer.postAnalyze(analyzer.analyze(preAnalyzer.preAnalyze(parser.createStatement(eql),
|
return optimizer.optimize(postAnalyzer.postAnalyze(analyzer.analyze(preAnalyzer.preAnalyze(parser.createStatement(eql),
|
||||||
resolution)), TEST_CFG_CASE_INSENSITIVE));
|
resolution)), TEST_CFG));
|
||||||
}
|
}
|
||||||
|
|
||||||
private LogicalPlan accept(String eql) {
|
private LogicalPlan accept(String eql) {
|
||||||
|
|
|
@ -29,8 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.singletonList;
|
import static java.util.Collections.singletonList;
|
||||||
import static java.util.stream.Collectors.toList;
|
import static java.util.stream.Collectors.toList;
|
||||||
import static org.elasticsearch.xpack.eql.EqlTestUtils.TEST_CFG_CASE_INSENSITIVE;
|
import static org.elasticsearch.xpack.eql.EqlTestUtils.TEST_CFG;
|
||||||
import static org.elasticsearch.xpack.eql.EqlTestUtils.TEST_CFG_CASE_SENSITIVE;
|
|
||||||
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
import static org.elasticsearch.xpack.ql.tree.Source.EMPTY;
|
||||||
|
|
||||||
public class TomlFoldTests extends ESTestCase {
|
public class TomlFoldTests extends ESTestCase {
|
||||||
|
@ -40,8 +39,7 @@ public class TomlFoldTests extends ESTestCase {
|
||||||
private static EqlParser parser = new EqlParser();
|
private static EqlParser parser = new EqlParser();
|
||||||
private static final EqlFunctionRegistry functionRegistry = new EqlFunctionRegistry();
|
private static final EqlFunctionRegistry functionRegistry = new EqlFunctionRegistry();
|
||||||
private static Verifier verifier = new Verifier(new Metrics());
|
private static Verifier verifier = new Verifier(new Metrics());
|
||||||
private static Analyzer caseSensitiveAnalyzer = new Analyzer(TEST_CFG_CASE_SENSITIVE, functionRegistry, verifier);
|
private static Analyzer analyzer = new Analyzer(TEST_CFG, functionRegistry, verifier);
|
||||||
private static Analyzer caseInsensitiveAnalyzer = new Analyzer(TEST_CFG_CASE_INSENSITIVE, functionRegistry, verifier);
|
|
||||||
|
|
||||||
private final int num;
|
private final int num;
|
||||||
private final EqlFoldSpec spec;
|
private final EqlFoldSpec spec;
|
||||||
|
@ -70,30 +68,6 @@ public class TomlFoldTests extends ESTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
// run both tests if case sensitivity doesn't matter
|
|
||||||
if (spec.caseSensitive() == null) {
|
|
||||||
testCaseSensitive(spec);
|
|
||||||
testCaseInsensitive(spec);
|
|
||||||
}
|
|
||||||
// run only the case sensitive test
|
|
||||||
else if (spec.caseSensitive()) {
|
|
||||||
testCaseSensitive(spec);
|
|
||||||
}
|
|
||||||
// run only the case insensitive test
|
|
||||||
else {
|
|
||||||
testCaseInsensitive(spec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testCaseSensitive(EqlFoldSpec spec) {
|
|
||||||
testWithAnalyzer(caseSensitiveAnalyzer, spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testCaseInsensitive(EqlFoldSpec spec) {
|
|
||||||
testWithAnalyzer(caseInsensitiveAnalyzer, spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testWithAnalyzer(Analyzer analyzer, EqlFoldSpec spec) {
|
|
||||||
Expression expr = parser.createExpression(spec.expression());
|
Expression expr = parser.createExpression(spec.expression());
|
||||||
LogicalPlan logicalPlan = new Project(EMPTY, new LocalRelation(EMPTY, emptyList()),
|
LogicalPlan logicalPlan = new Project(EMPTY, new LocalRelation(EMPTY, emptyList()),
|
||||||
singletonList(new Alias(Source.EMPTY, "test", expr)));
|
singletonList(new Alias(Source.EMPTY, "test", expr)));
|
||||||
|
|
|
@ -33,13 +33,13 @@ public class QueryFolderFailTests extends AbstractQueryFolderTestCase {
|
||||||
"process where between(process_name, \"s\") == \"yst\"",
|
"process where between(process_name, \"s\") == \"yst\"",
|
||||||
"process where between(null) == \"yst\"",
|
"process where between(null) == \"yst\"",
|
||||||
"process where between(process_name, null) == \"yst\"",
|
"process where between(process_name, null) == \"yst\"",
|
||||||
"process where between(process_name, \"s\", \"e\", false, false, true) == \"yst\"",
|
"process where between(process_name, \"s\", \"e\", false, false) == \"yst\"",
|
||||||
};
|
};
|
||||||
|
|
||||||
for (String query : queries) {
|
for (String query : queries) {
|
||||||
ParsingException e = expectThrows(ParsingException.class,
|
ParsingException e = expectThrows(ParsingException.class,
|
||||||
() -> plan(query));
|
() -> plan(query));
|
||||||
assertEquals("line 1:16: error building [between]: expects between three and five arguments", e.getMessage());
|
assertEquals("line 1:16: error building [between]: expects three or four arguments", e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,10 +56,6 @@ public class QueryFolderFailTests extends AbstractQueryFolderTestCase {
|
||||||
assertEquals("1:15: fourth argument of [between(process_name, \"s\", \"e\", \"true\")] must be [boolean], " +
|
assertEquals("1:15: fourth argument of [between(process_name, \"s\", \"e\", \"true\")] must be [boolean], " +
|
||||||
"found value [\"true\"] type [keyword]",
|
"found value [\"true\"] type [keyword]",
|
||||||
error("process where between(process_name, \"s\", \"e\", \"true\")"));
|
error("process where between(process_name, \"s\", \"e\", \"true\")"));
|
||||||
|
|
||||||
assertEquals("1:15: fifth argument of [between(process_name, \"s\", \"e\", false, 2)] must be [boolean], " +
|
|
||||||
"found value [2] type [integer]",
|
|
||||||
error("process where between(process_name, \"s\", \"e\", false, 2)"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCIDRMatchAgainstField() {
|
public void testCIDRMatchAgainstField() {
|
||||||
|
|
|
@ -10,14 +10,12 @@ import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.xpack.eql.plan.physical.EsQueryExec;
|
import org.elasticsearch.xpack.eql.plan.physical.EsQueryExec;
|
||||||
import org.elasticsearch.xpack.eql.plan.physical.PhysicalPlan;
|
import org.elasticsearch.xpack.eql.plan.physical.PhysicalPlan;
|
||||||
import org.junit.Assume;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
@ -110,13 +108,6 @@ public class QueryFolderOkTests extends AbstractQueryFolderTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void test() {
|
public void test() {
|
||||||
String testName = name.toLowerCase(Locale.ROOT);
|
|
||||||
// skip tests that do not make sense from case sensitivity point of view
|
|
||||||
boolean isCaseSensitiveValidTest = testName.endsWith("sensitive") == false
|
|
||||||
|| testName.endsWith("-casesensitive") && configuration.isCaseSensitive()
|
|
||||||
|| testName.endsWith("-caseinsensitive") && configuration.isCaseSensitive() == false;
|
|
||||||
Assume.assumeTrue(isCaseSensitiveValidTest);
|
|
||||||
|
|
||||||
PhysicalPlan p = plan(query);
|
PhysicalPlan p = plan(query);
|
||||||
assertEquals(EsQueryExec.class, p.getClass());
|
assertEquals(EsQueryExec.class, p.getClass());
|
||||||
EsQueryExec eqe = (EsQueryExec) p;
|
EsQueryExec eqe = (EsQueryExec) p;
|
||||||
|
|
|
@ -23,6 +23,8 @@ registry where not pid;
|
||||||
|
|
||||||
process where process_name : "net.exe" and command_line : "* user*.exe";
|
process where process_name : "net.exe" and command_line : "* user*.exe";
|
||||||
|
|
||||||
|
process where process_name : "net.EXE" and command_line : "* user*.EXE";
|
||||||
|
|
||||||
process where command_line : "~!@#$%^&*();'[]{}\\|<>?,./:\"-= ' ";
|
process where command_line : "~!@#$%^&*();'[]{}\\|<>?,./:\"-= ' ";
|
||||||
|
|
||||||
process where
|
process where
|
||||||
|
@ -33,6 +35,8 @@ process where process_name in ("net.exe", "cmd.exe", "at.exe");
|
||||||
|
|
||||||
process where command_line : "*.exe *admin*" or command_line : "* a b*";
|
process where command_line : "*.exe *admin*" or command_line : "* a b*";
|
||||||
|
|
||||||
|
process where command_line : "*.eXe *aDMin*" or command_line : "* a b*";
|
||||||
|
|
||||||
process where pid in (1,2,3,4,5,6,7,8) and abc : 100 and def : 200 and ghi : 300 and jkl : x;
|
process where pid in (1,2,3,4,5,6,7,8) and abc : 100 and def : 200 and ghi : 300 and jkl : x;
|
||||||
|
|
||||||
process where ppid != pid;
|
process where ppid != pid;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
// ...
|
// ...
|
||||||
// <expectation n>
|
// <expectation n>
|
||||||
// ;
|
// ;
|
||||||
|
// NOTE: do not use whitespaces in the relevant parts of the query itself, as they will be removed. For example 'process where process_name : "System Idle Process"'
|
||||||
|
// The whitespaces between System Idle Process will be removed and the assertion will fail.
|
||||||
|
|
||||||
|
|
||||||
basic
|
basic
|
||||||
|
@ -21,7 +23,7 @@ null
|
||||||
singleNumericFilterEquals
|
singleNumericFilterEquals
|
||||||
process where serial_event_id == 1
|
process where serial_event_id == 1
|
||||||
;
|
;
|
||||||
"term":{"serial_event_id":{"value":1
|
"term":{"serial_event_id":{"value":1,"boost":1.0}
|
||||||
;
|
;
|
||||||
|
|
||||||
singleNumericFilterLess
|
singleNumericFilterLess
|
||||||
|
@ -48,10 +50,16 @@ process where serial_event_id >= 4
|
||||||
"range":{"serial_event_id":{"from":4,"to":null,"include_lower":true,"include_upper":false
|
"range":{"serial_event_id":{"from":4,"to":null,"include_lower":true,"include_upper":false
|
||||||
;
|
;
|
||||||
|
|
||||||
|
caseInsensitiveEquals
|
||||||
|
process where process_name : "test"
|
||||||
|
;
|
||||||
|
"term":{"process_name":{"value":"test","case_insensitive":true,"boost":1.0}
|
||||||
|
;
|
||||||
|
|
||||||
mixedTypeFilter
|
mixedTypeFilter
|
||||||
process where process_name : "notepad.exe" or (serial_event_id < 4.5 and serial_event_id >= 3.1)
|
process where process_name : "notepad.exe" or (serial_event_id < 4.5 and serial_event_id >= 3.1)
|
||||||
;
|
;
|
||||||
"term":{"process_name":{"value":"notepad.exe"
|
"term":{"process_name":{"value":"notepad.exe","case_insensitive":true,"boost":1.0}
|
||||||
"range":{"serial_event_id":{"from":3.1,"to":4.5,"include_lower":true,"include_upper":false
|
"range":{"serial_event_id":{"from":3.1,"to":4.5,"include_lower":true,"include_upper":false
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -70,35 +78,35 @@ process where process_name in ("python.exe", "SMSS.exe", "explorer.exe")
|
||||||
equalsAndInFilter
|
equalsAndInFilter
|
||||||
process where process_path : "*\\red_ttp\\wininit.*" and opcode in (0,1,2,3)
|
process where process_path : "*\\red_ttp\\wininit.*" and opcode in (0,1,2,3)
|
||||||
;
|
;
|
||||||
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
|
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*","case_insensitive":true,"boost":1.0}}},
|
||||||
{"terms":{"opcode":[0,1,2,3]
|
{"terms":{"opcode":[0,1,2,3],"boost":1.0}}
|
||||||
;
|
;
|
||||||
|
|
||||||
functionEqualsTrue
|
functionEqualsTrue
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8") == true
|
process where cidrMatch(source_address, "10.0.0.0/8") == true
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"terms":{"source_address":["10.0.0.0/8"]
|
{"terms":{"source_address":["10.0.0.0/8"]
|
||||||
;
|
;
|
||||||
|
|
||||||
functionEqualsFalse
|
functionEqualsFalse
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8") == false
|
process where cidrMatch(source_address, "10.0.0.0/8") == false
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"bool":{"must_not":[{"terms":{"source_address":["10.0.0.0/8"]
|
{"bool":{"must_not":[{"terms":{"source_address":["10.0.0.0/8"]
|
||||||
;
|
;
|
||||||
|
|
||||||
functionNotEqualsTrue
|
functionNotEqualsTrue
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8") != true
|
process where cidrMatch(source_address, "10.0.0.0/8") != true
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"bool":{"must_not":[{"terms":{"source_address":["10.0.0.0/8"]
|
{"bool":{"must_not":[{"terms":{"source_address":["10.0.0.0/8"]
|
||||||
;
|
;
|
||||||
|
|
||||||
functionNotEqualsFalse
|
functionNotEqualsFalse
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8") != false
|
process where cidrMatch(source_address, "10.0.0.0/8") != false
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"terms":{"source_address":["10.0.0.0/8"]
|
{"terms":{"source_address":["10.0.0.0/8"]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -112,13 +120,8 @@ process where endsWith(process_path, "x") == true and endsWith(process_path, "yx
|
||||||
twoFunctionsEqualsBooleanLiterals-caseInsensitive
|
twoFunctionsEqualsBooleanLiterals-caseInsensitive
|
||||||
process where endsWith(process_path, "x") == true and endsWith(process_path, "yx") != true
|
process where endsWith(process_path, "x") == true and endsWith(process_path, "yx") != true
|
||||||
;
|
;
|
||||||
"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"wildcard":{"process_path":{"wildcard":"*x","boost":1.0}}},
|
||||||
"must":[{"script":{"script":{"source":"InternalQlScriptUtils.nullSafeFilter(
|
{"bool":{"must_not":[{"wildcard":{"process_path":{"wildcard":"*yx","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}],"adjust_pure_negative":true,"boost":1.0}}
|
||||||
InternalEqlScriptUtils.endsWith(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2))","lang":"painless",
|
|
||||||
"params":{"v0":"process_path","v1":"x","v2":false}}
|
|
||||||
"script":{"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.not(
|
|
||||||
InternalEqlScriptUtils.endsWith(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2)))","lang":"painless",
|
|
||||||
"params":{"v0":"process_path","v1":"yx","v2":false}}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
endsWithKeywordFieldFunction-caseSensitive
|
endsWithKeywordFieldFunction-caseSensitive
|
||||||
|
@ -138,9 +141,8 @@ process where endsWith(hostname, "c")
|
||||||
endsWithFunction-caseInsensitive
|
endsWithFunction-caseInsensitive
|
||||||
process where endsWith(user_name, "c")
|
process where endsWith(user_name, "c")
|
||||||
;
|
;
|
||||||
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.endsWith(
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}}},
|
||||||
InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2))",
|
{"wildcard":{"user_name":{"wildcard":"*c","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}
|
||||||
"params":{"v0":"user_name","v1":"c","v2":false}}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
lengthFunctionWithExactSubField
|
lengthFunctionWithExactSubField
|
||||||
|
@ -170,9 +172,8 @@ InternalEqlScriptUtils.length(InternalQlScriptUtils.docValue(doc,params.v0)),par
|
||||||
startsWithFunction-caseInsensitive
|
startsWithFunction-caseInsensitive
|
||||||
process where startsWith(user_name, "A")
|
process where startsWith(user_name, "A")
|
||||||
;
|
;
|
||||||
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.startsWith(
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}}},
|
||||||
InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2))",
|
{"prefix":{"user_name":{"value":"A","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}
|
||||||
"params":{"v0":"user_name","v1":"A","v2":false}}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
startsWithFunctionSimple-caseSensitive
|
startsWithFunctionSimple-caseSensitive
|
||||||
|
@ -207,9 +208,8 @@ process where stringContains(hostname, "foo")
|
||||||
stringContains-caseInsensitive
|
stringContains-caseInsensitive
|
||||||
process where stringContains(process_name, "foo")
|
process where stringContains(process_name, "foo")
|
||||||
;
|
;
|
||||||
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.stringContains(
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}}},
|
||||||
InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2))"
|
{"wildcard":{"process_name":{"wildcard":"*foo*","boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}
|
||||||
"params":{"v0":"process_name","v1":"foo","v2":false}
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ process where indexOf(user_name, "A", 2) > 0
|
||||||
;
|
;
|
||||||
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.gt(
|
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalQlScriptUtils.gt(
|
||||||
InternalEqlScriptUtils.indexOf(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2,params.v3),params.v4))",
|
InternalEqlScriptUtils.indexOf(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2,params.v3),params.v4))",
|
||||||
"params":{"v0":"user_name","v1":"A","v2":2,"v3":false,"v4":0}
|
"params":{"v0":"user_name","v1":"A","v2":2,"v3":true,"v4":0}
|
||||||
;
|
;
|
||||||
|
|
||||||
substringFunction
|
substringFunction
|
||||||
|
@ -250,7 +250,7 @@ process where between(process_name, "s", "e") : "yst"
|
||||||
;
|
;
|
||||||
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.seq(
|
"script":{"source":"InternalQlScriptUtils.nullSafeFilter(InternalEqlScriptUtils.seq(
|
||||||
InternalEqlScriptUtils.between(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2,params.v3,params.v4),params.v5))",
|
InternalEqlScriptUtils.between(InternalQlScriptUtils.docValue(doc,params.v0),params.v1,params.v2,params.v3,params.v4),params.v5))",
|
||||||
"params":{"v0":"process_name","v1":"s","v2":"e","v3":false,"v4":false,"v5":"yst"}
|
"params":{"v0":"process_name","v1":"s","v2":"e","v3":false,"v4":true,"v5":"yst"}
|
||||||
;
|
;
|
||||||
|
|
||||||
concatFunction
|
concatFunction
|
||||||
|
@ -264,35 +264,35 @@ InternalEqlScriptUtils.concat([InternalQlScriptUtils.docValue(doc,params.v0),par
|
||||||
cidrMatchFunctionOne
|
cidrMatchFunctionOne
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8")
|
process where cidrMatch(source_address, "10.0.0.0/8")
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"terms":{"source_address":["10.0.0.0/8"]
|
{"terms":{"source_address":["10.0.0.0/8"]
|
||||||
;
|
;
|
||||||
|
|
||||||
cidrMatchFunctionOneBool
|
cidrMatchFunctionOneBool
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8") == true
|
process where cidrMatch(source_address, "10.0.0.0/8") == true
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"terms":{"source_address":["10.0.0.0/8"]
|
{"terms":{"source_address":["10.0.0.0/8"]
|
||||||
;
|
;
|
||||||
|
|
||||||
cidrMatchFunctionTwo
|
cidrMatchFunctionTwo
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8", "192.168.0.0/16")
|
process where cidrMatch(source_address, "10.0.0.0/8", "192.168.0.0/16")
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"terms":{"source_address":["10.0.0.0/8","192.168.0.0/16"]
|
{"terms":{"source_address":["10.0.0.0/8","192.168.0.0/16"]
|
||||||
;
|
;
|
||||||
|
|
||||||
cidrMatchFunctionTwoWithOr
|
cidrMatchFunctionTwoWithOr
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8") or cidrMatch(source_address, "192.168.0.0/16")
|
process where cidrMatch(source_address, "10.0.0.0/8") or cidrMatch(source_address, "192.168.0.0/16")
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"bool":{"should":[{"terms":{"source_address":["10.0.0.0/8"],"boost":1.0}},{"terms":{"source_address":["192.168.0.0/16"],"boost":1.0}}
|
{"bool":{"should":[{"terms":{"source_address":["10.0.0.0/8"],"boost":1.0}},{"terms":{"source_address":["192.168.0.0/16"],"boost":1.0}}
|
||||||
;
|
;
|
||||||
|
|
||||||
cidrMatchFunctionThree
|
cidrMatchFunctionThree
|
||||||
process where cidrMatch(source_address, "10.0.0.0/8", "192.168.0.0/16", "2001:db8::/32")
|
process where cidrMatch(source_address, "10.0.0.0/8", "192.168.0.0/16", "2001:db8::/32")
|
||||||
;
|
;
|
||||||
{"bool":{"must":[{"term":{"event.category":{"value":"process"
|
{"bool":{"must":[{"term":{"event.category":{"value":"process","boost":1.0}
|
||||||
{"terms":{"source_address":["10.0.0.0/8","192.168.0.0/16","2001:db8::/32"]
|
{"terms":{"source_address":["10.0.0.0/8","192.168.0.0/16","2001:db8::/32"]
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -351,34 +351,34 @@ InternalEqlScriptUtils.number(InternalQlScriptUtils.docValue(doc,params.v0),para
|
||||||
|
|
||||||
numberFunctionFoldedComparison
|
numberFunctionFoldedComparison
|
||||||
process where serial_event_id == number("-32.5");
|
process where serial_event_id == number("-32.5");
|
||||||
{"term":{"serial_event_id":{"value":-32.5,
|
{"term":{"serial_event_id":{"value":-32.5,"boost":1.0}
|
||||||
;
|
;
|
||||||
|
|
||||||
numberFunctionFoldedHexComparison
|
numberFunctionFoldedHexComparison
|
||||||
process where serial_event_id == number("0x32", 16);
|
process where serial_event_id == number("0x32", 16);
|
||||||
{"term":{"serial_event_id":{"value":50,
|
{"term":{"serial_event_id":{"value":50,"boost":1.0}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
wildcardFunctionSingleArgument
|
wildcardFunctionSingleArgument
|
||||||
process where wildcard(process_path, "*\\red_ttp\\wininit.*")
|
process where wildcard(process_path, "*\\red_ttp\\wininit.*")
|
||||||
;
|
;
|
||||||
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
|
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*","boost":1.0}}
|
||||||
;
|
;
|
||||||
|
|
||||||
wildcardFunctionTwoArguments
|
wildcardFunctionTwoArguments
|
||||||
process where wildcard(process_path, "*\\red_ttp\\wininit.*", "*\\abc\\*")
|
process where wildcard(process_path, "*\\red_ttp\\wininit.*", "*\\abc\\*")
|
||||||
;
|
;
|
||||||
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
|
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*","boost":1.0}}
|
||||||
"wildcard":{"process_path":{"wildcard":"*\\\\abc\\\\*"
|
"wildcard":{"process_path":{"wildcard":"*\\\\abc\\\\*","boost":1.0}}
|
||||||
;
|
;
|
||||||
|
|
||||||
wildcardFunctionThreeArguments
|
wildcardFunctionThreeArguments
|
||||||
process where wildcard(process_path, "*\\red_ttp\\wininit.*", "*\\abc\\*", "*def*")
|
process where wildcard(process_path, "*\\red_ttp\\wininit.*", "*\\abc\\*", "*def*")
|
||||||
;
|
;
|
||||||
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*"
|
"wildcard":{"process_path":{"wildcard":"*\\\\red_ttp\\\\wininit.*","boost":1.0}}
|
||||||
"wildcard":{"process_path":{"wildcard":"*\\\\abc\\\\*"
|
"wildcard":{"process_path":{"wildcard":"*\\\\abc\\\\*","boost":1.0}}
|
||||||
"wildcard":{"process_path":{"wildcard":"*def*"
|
"wildcard":{"process_path":{"wildcard":"*def*","boost":1.0}}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,6 @@ description = "Fold string comparisons"
|
||||||
|
|
||||||
[string_case_sensitive_match_comparison]
|
[string_case_sensitive_match_comparison]
|
||||||
description = "Fold string comparisons"
|
description = "Fold string comparisons"
|
||||||
case_sensitive = true
|
|
||||||
|
|
||||||
[[string_case_sensitive_match_comparison.fold.tests]]
|
[[string_case_sensitive_match_comparison.fold.tests]]
|
||||||
expression = '"Foo" == "foo"'
|
expression = '"Foo" == "foo"'
|
||||||
|
|
|
@ -104,16 +104,14 @@ description = "Test the `endsWith` function with case matching"
|
||||||
|
|
||||||
[endswith_insensitive]
|
[endswith_insensitive]
|
||||||
description = "Test the `endsWith` function with case insensitivity"
|
description = "Test the `endsWith` function with case insensitivity"
|
||||||
case_insensitive = true
|
|
||||||
|
|
||||||
[[endswith_insensitive.fold.tests]]
|
[[endswith_insensitive.fold.tests]]
|
||||||
expression = 'endsWith("FooBarBaz", "baz")'
|
expression = 'endsWith("FooBarBaz", "baz")'
|
||||||
expected = true
|
expected = false
|
||||||
|
|
||||||
|
|
||||||
[endswith_sensitive]
|
[endswith_sensitive]
|
||||||
description = "Test the `endsWith` function with case sensitivity"
|
description = "Test the `endsWith` function with case sensitivity"
|
||||||
case_sensitive = true
|
|
||||||
|
|
||||||
[[endswith_sensitive.fold.tests]]
|
[[endswith_sensitive.fold.tests]]
|
||||||
expression = 'endsWith("FooBarBaz", "baz")'
|
expression = 'endsWith("FooBarBaz", "baz")'
|
||||||
|
@ -331,7 +329,6 @@ description = "Test the `startsWith` function"
|
||||||
|
|
||||||
[startswith_case_sensitive]
|
[startswith_case_sensitive]
|
||||||
description = "Test the `startsWith` function with case-sensitive matching"
|
description = "Test the `startsWith` function with case-sensitive matching"
|
||||||
case_sensitive = true
|
|
||||||
|
|
||||||
[[startswith_case_sensitive.tests]]
|
[[startswith_case_sensitive.tests]]
|
||||||
expression = '''startsWith("FooBar", "Foo")'''
|
expression = '''startsWith("FooBar", "Foo")'''
|
||||||
|
@ -344,7 +341,6 @@ case_sensitive = true
|
||||||
|
|
||||||
[startswith_case_insensitive]
|
[startswith_case_insensitive]
|
||||||
description = "Test the `startsWith` function with case-insensitive matching"
|
description = "Test the `startsWith` function with case-insensitive matching"
|
||||||
case_insensitive = true
|
|
||||||
|
|
||||||
[[startswith_case_insensitive.fold.tests]]
|
[[startswith_case_insensitive.fold.tests]]
|
||||||
expression = '''startsWith("FooBar", "Foo")'''
|
expression = '''startsWith("FooBar", "Foo")'''
|
||||||
|
@ -352,11 +348,11 @@ case_insensitive = true
|
||||||
|
|
||||||
[[startswith_case_insensitive.fold.tests]]
|
[[startswith_case_insensitive.fold.tests]]
|
||||||
expression = '''startsWith("FooBar", "FOO")'''
|
expression = '''startsWith("FooBar", "FOO")'''
|
||||||
expected = true
|
expected = false
|
||||||
|
|
||||||
[[startswith_case_insensitive.fold.tests]]
|
[[startswith_case_insensitive.fold.tests]]
|
||||||
expression = '''startsWith("FooBar", "foo")'''
|
expression = '''startsWith("FooBar", "foo")'''
|
||||||
expected = true
|
expected = false
|
||||||
|
|
||||||
[[startswith_case_insensitive.fold.tests]]
|
[[startswith_case_insensitive.fold.tests]]
|
||||||
expression = '''startsWith("FooBar", "Bar")'''
|
expression = '''startsWith("FooBar", "Bar")'''
|
||||||
|
@ -498,11 +494,10 @@ description = "Test that `wildcard` folds with correct case matches."
|
||||||
|
|
||||||
[wildcard_case_insensitive]
|
[wildcard_case_insensitive]
|
||||||
description = "Test that `wildcard` function folds case insensitive as expected."
|
description = "Test that `wildcard` function folds case insensitive as expected."
|
||||||
case_insensitive = true
|
|
||||||
|
|
||||||
[[wildcard_case_insensitive.fold.tests]]
|
[[wildcard_case_insensitive.fold.tests]]
|
||||||
expression = 'wildcard("FOO", "f*o*o*")'
|
expression = 'wildcard("FOO", "f*o*o*")'
|
||||||
expected = true
|
expected = false
|
||||||
|
|
||||||
[[wildcard_case_insensitive.fold.tests]]
|
[[wildcard_case_insensitive.fold.tests]]
|
||||||
expression = 'wildcard("bar", "f*o*o*")'
|
expression = 'wildcard("bar", "f*o*o*")'
|
||||||
|
@ -511,7 +506,6 @@ case_insensitive = true
|
||||||
|
|
||||||
[wildcard_case_sensitive]
|
[wildcard_case_sensitive]
|
||||||
description = "Test that `wildcard` folds case-sensitive matches."
|
description = "Test that `wildcard` folds case-sensitive matches."
|
||||||
case_sensitive = true
|
|
||||||
|
|
||||||
[[wildcard_case_sensitive.fold.tests]]
|
[[wildcard_case_sensitive.fold.tests]]
|
||||||
expression = 'wildcard("Foo", "F*o*o*")'
|
expression = 'wildcard("Foo", "F*o*o*")'
|
||||||
|
|
|
@ -420,13 +420,16 @@ public class FunctionRegistry {
|
||||||
public static <T extends Function> FunctionDefinition def(Class<T> function,
|
public static <T extends Function> FunctionDefinition def(Class<T> function,
|
||||||
FourParametersFunctionBuilder<T> ctorRef, String... names) {
|
FourParametersFunctionBuilder<T> ctorRef, String... names) {
|
||||||
FunctionBuilder builder = (source, children, distinct, cfg) -> {
|
FunctionBuilder builder = (source, children, distinct, cfg) -> {
|
||||||
if (children.size() != 4) {
|
boolean hasMinimumThree = OptionalArgument.class.isAssignableFrom(function);
|
||||||
|
if (hasMinimumThree && (children.size() > 4 || children.size() < 3)) {
|
||||||
|
throw new QlIllegalArgumentException("expects three or four arguments");
|
||||||
|
} else if (!hasMinimumThree && children.size() != 4) {
|
||||||
throw new QlIllegalArgumentException("expects exactly four arguments");
|
throw new QlIllegalArgumentException("expects exactly four arguments");
|
||||||
}
|
}
|
||||||
if (distinct) {
|
if (distinct) {
|
||||||
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
|
throw new QlIllegalArgumentException("does not support DISTINCT yet it was specified");
|
||||||
}
|
}
|
||||||
return ctorRef.build(source, children.get(0), children.get(1), children.get(2), children.get(3));
|
return ctorRef.build(source, children.get(0), children.get(1), children.get(2), children.size() == 4 ? children.get(3) : null);
|
||||||
};
|
};
|
||||||
return def(function, builder, false, names);
|
return def(function, builder, false, names);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,19 +9,43 @@ import org.elasticsearch.xpack.ql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.ql.tree.NodeInfo;
|
import org.elasticsearch.xpack.ql.tree.NodeInfo;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
public class Like extends RegexMatch<LikePattern> {
|
public class Like extends RegexMatch<LikePattern> {
|
||||||
|
|
||||||
|
private final boolean caseInsensitive;
|
||||||
|
|
||||||
public Like(Source source, Expression left, LikePattern pattern) {
|
public Like(Source source, Expression left, LikePattern pattern) {
|
||||||
|
this(source, left, pattern, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Like(Source source, Expression left, LikePattern pattern, boolean caseInsensitive) {
|
||||||
super(source, left, pattern);
|
super(source, left, pattern);
|
||||||
|
this.caseInsensitive = caseInsensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected NodeInfo<Like> info() {
|
protected NodeInfo<Like> info() {
|
||||||
return NodeInfo.create(this, Like::new, field(), pattern());
|
return NodeInfo.create(this, Like::new, field(), pattern(), caseInsensitive());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Like replaceChild(Expression newLeft) {
|
protected Like replaceChild(Expression newLeft) {
|
||||||
return new Like(source(), newLeft, pattern());
|
return new Like(source(), newLeft, pattern(), caseInsensitive());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean caseInsensitive() {
|
||||||
|
return caseInsensitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return super.equals(obj) && Objects.equals(((Like) obj).caseInsensitive(), caseInsensitive());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(super.hashCode(), caseInsensitive());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.LessT
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.NotEquals;
|
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.NotEquals;
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.NullEquals;
|
import org.elasticsearch.xpack.ql.expression.predicate.operator.comparison.NullEquals;
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.regex.Like;
|
import org.elasticsearch.xpack.ql.expression.predicate.regex.Like;
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.regex.LikePattern;
|
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.regex.RLike;
|
import org.elasticsearch.xpack.ql.expression.predicate.regex.RLike;
|
||||||
import org.elasticsearch.xpack.ql.expression.predicate.regex.RegexMatch;
|
import org.elasticsearch.xpack.ql.expression.predicate.regex.RegexMatch;
|
||||||
import org.elasticsearch.xpack.ql.querydsl.query.BoolQuery;
|
import org.elasticsearch.xpack.ql.querydsl.query.BoolQuery;
|
||||||
|
@ -127,8 +126,8 @@ public final class ExpressionTranslators {
|
||||||
if (e.field() instanceof FieldAttribute) {
|
if (e.field() instanceof FieldAttribute) {
|
||||||
targetFieldName = handler.nameOf(((FieldAttribute) e.field()).exactAttribute());
|
targetFieldName = handler.nameOf(((FieldAttribute) e.field()).exactAttribute());
|
||||||
if (e instanceof Like) {
|
if (e instanceof Like) {
|
||||||
LikePattern p = ((Like) e).pattern();
|
Like l = (Like) e;
|
||||||
q = new WildcardQuery(e.source(), targetFieldName, p.asLuceneWildcard());
|
q = new WildcardQuery(e.source(), targetFieldName, l.pattern().asLuceneWildcard(), l.caseInsensitive());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e instanceof RLike) {
|
if (e instanceof RLike) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package org.elasticsearch.xpack.ql.querydsl.query;
|
package org.elasticsearch.xpack.ql.querydsl.query;
|
||||||
|
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.TermQueryBuilder;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -16,11 +17,17 @@ public class TermQuery extends LeafQuery {
|
||||||
|
|
||||||
private final String term;
|
private final String term;
|
||||||
private final Object value;
|
private final Object value;
|
||||||
|
private final boolean caseInsensitive;
|
||||||
|
|
||||||
public TermQuery(Source source, String term, Object value) {
|
public TermQuery(Source source, String term, Object value) {
|
||||||
|
this(source, term, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TermQuery(Source source, String term, Object value, boolean caseInsensitive) {
|
||||||
super(source);
|
super(source);
|
||||||
this.term = term;
|
this.term = term;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.caseInsensitive = caseInsensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String term() {
|
public String term() {
|
||||||
|
@ -31,14 +38,20 @@ public class TermQuery extends LeafQuery {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean caseInsensitive() {
|
||||||
|
return caseInsensitive;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryBuilder asBuilder() {
|
public QueryBuilder asBuilder() {
|
||||||
return termQuery(term, value);
|
TermQueryBuilder qb = termQuery(term, value);
|
||||||
|
// ES does not allow case_insensitive to be set to "false", it should be either "true" or not specified
|
||||||
|
return caseInsensitive == false ? qb : qb.caseInsensitive(caseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(term, value);
|
return Objects.hash(term, value, caseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -53,7 +66,8 @@ public class TermQuery extends LeafQuery {
|
||||||
|
|
||||||
TermQuery other = (TermQuery) obj;
|
TermQuery other = (TermQuery) obj;
|
||||||
return Objects.equals(term, other.term)
|
return Objects.equals(term, other.term)
|
||||||
&& Objects.equals(value, other.value);
|
&& Objects.equals(value, other.value)
|
||||||
|
&& Objects.equals(caseInsensitive, other.caseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
package org.elasticsearch.xpack.ql.querydsl.query;
|
package org.elasticsearch.xpack.ql.querydsl.query;
|
||||||
|
|
||||||
import org.elasticsearch.index.query.QueryBuilder;
|
import org.elasticsearch.index.query.QueryBuilder;
|
||||||
|
import org.elasticsearch.index.query.WildcardQueryBuilder;
|
||||||
import org.elasticsearch.xpack.ql.tree.Source;
|
import org.elasticsearch.xpack.ql.tree.Source;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -15,11 +16,17 @@ import static org.elasticsearch.index.query.QueryBuilders.wildcardQuery;
|
||||||
public class WildcardQuery extends LeafQuery {
|
public class WildcardQuery extends LeafQuery {
|
||||||
|
|
||||||
private final String field, query;
|
private final String field, query;
|
||||||
|
private final boolean caseInsensitive;
|
||||||
|
|
||||||
public WildcardQuery(Source source, String field, String query) {
|
public WildcardQuery(Source source, String field, String query) {
|
||||||
|
this(source, field, query, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WildcardQuery(Source source, String field, String query, boolean caseInsensitive) {
|
||||||
super(source);
|
super(source);
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
|
this.caseInsensitive = caseInsensitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String field() {
|
public String field() {
|
||||||
|
@ -30,14 +37,20 @@ public class WildcardQuery extends LeafQuery {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Boolean caseInsensitive() {
|
||||||
|
return caseInsensitive;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public QueryBuilder asBuilder() {
|
public QueryBuilder asBuilder() {
|
||||||
return wildcardQuery(field, query);
|
WildcardQueryBuilder wb = wildcardQuery(field, query);
|
||||||
|
// ES does not allow case_insensitive to be set to "false", it should be either "true" or not specified
|
||||||
|
return caseInsensitive == false ? wb : wb.caseInsensitive(caseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(field, query);
|
return Objects.hash(field, query, caseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -52,7 +65,8 @@ public class WildcardQuery extends LeafQuery {
|
||||||
|
|
||||||
WildcardQuery other = (WildcardQuery) obj;
|
WildcardQuery other = (WildcardQuery) obj;
|
||||||
return Objects.equals(field, other.field)
|
return Objects.equals(field, other.field)
|
||||||
&& Objects.equals(query, other.query);
|
&& Objects.equals(query, other.query)
|
||||||
|
&& Objects.equals(caseInsensitive, other.caseInsensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue