mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-05 16:10:43 +00:00
fix: use str_match replace LIKE for contains for alert (#7670)
### **User description**
str_match we can use secondary index now.
___
### **PR Type**
Bug fix, Enhancement
___
### **Description**
- Expose secondary index fields in config response
- Replace SQL LIKE with `str_match` for contains
___
<details> <summary><h3> File Walkthrough</h3></summary>
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Configuration
changes</strong></td><td><table>
<tr>
<td>
<details>
<summary><strong>mod.rs</strong><dd><code>Expose secondary index in
config response</code>
</dd></summary>
<hr>
src/handler/http/request/status/mod.rs
<ul><li>Imported <code>SQL_SECONDARY_INDEX_SEARCH_FIELDS</code> constant
<br> <li> Added <code>default_secondary_index_fields</code> to
<code>ConfigResponse</code> <br> <li> Populated new field in
<code>zo_config</code> handler</ul>
</details>
</td>
<td><a
href="https://github.com/openobserve/openobserve/pull/7670/files#diff-ca09c9c9b020049bdbc3382c466bfcca80daac92e98760d9a9a76172abf34049">+7/-1</a>
</td>
</tr>
</table></td></tr><tr><td><strong>Bug fix</strong></td><td><table>
<tr>
<td>
<details>
<summary><strong>mod.rs</strong><dd><code>Use `str_match` for contains
operator</code>
</dd></summary>
<hr>
src/service/alerts/mod.rs
<ul><li>Replaced <code>LIKE '%value%'</code> with <code>str_match</code>
for <code>Contains</code> <br> <li> Left <code>NotContains</code> using
<code>NOT LIKE</code> unchanged</ul>
</details>
</td>
<td><a
href="https://github.com/openobserve/openobserve/pull/7670/files#diff-ba9b65130898444f7815fd6068bdb0dc590612f74cc893f79d91b0afc44cc851">+1/-1</a>
</td>
</tr>
</table></td></tr></tr></tbody></table>
</details>
___
This commit is contained in:
+20
-13
@@ -117,20 +117,27 @@ pub static SQL_FULL_TEXT_SEARCH_FIELDS: Lazy<Vec<String>> = Lazy::new(|| {
|
||||
fields
|
||||
});
|
||||
|
||||
const _DEFAULT_SQL_SECONDARY_INDEX_SEARCH_FIELDS: [&str; 3] =
|
||||
["trace_id", "service_name", "operation_name"];
|
||||
pub static SQL_SECONDARY_INDEX_SEARCH_FIELDS: Lazy<Vec<String>> = Lazy::new(|| {
|
||||
let mut fields = get_config()
|
||||
.common
|
||||
.feature_secondary_index_extra_fields
|
||||
.split(',')
|
||||
.filter_map(|s| {
|
||||
let s = s.trim();
|
||||
if s.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(s.to_string())
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut fields = chain(
|
||||
_DEFAULT_SQL_SECONDARY_INDEX_SEARCH_FIELDS
|
||||
.iter()
|
||||
.map(|s| s.to_string()),
|
||||
get_config()
|
||||
.common
|
||||
.feature_secondary_index_extra_fields
|
||||
.split(',')
|
||||
.filter_map(|s| {
|
||||
let s = s.trim();
|
||||
if s.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(s.to_string())
|
||||
}
|
||||
}),
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
fields.sort();
|
||||
fields.dedup();
|
||||
fields
|
||||
|
||||
@@ -24,7 +24,8 @@ use actix_web::{
|
||||
};
|
||||
use arrow_schema::Schema;
|
||||
use config::{
|
||||
Config, META_ORG_ID, QUICK_MODEL_FIELDS, SQL_FULL_TEXT_SEARCH_FIELDS, TIMESTAMP_COL_NAME,
|
||||
Config, META_ORG_ID, QUICK_MODEL_FIELDS, SQL_FULL_TEXT_SEARCH_FIELDS,
|
||||
SQL_SECONDARY_INDEX_SEARCH_FIELDS, TIMESTAMP_COL_NAME,
|
||||
cluster::LOCAL_NODE,
|
||||
get_config, get_instance_id,
|
||||
meta::{
|
||||
@@ -92,6 +93,7 @@ struct ConfigResponse<'a> {
|
||||
build_date: String,
|
||||
build_type: String,
|
||||
default_fts_keys: Vec<String>,
|
||||
default_secondary_index_fields: Vec<String>,
|
||||
default_quick_mode_fields: Vec<String>,
|
||||
telemetry_enabled: bool,
|
||||
default_functions: Vec<ZoFunction<'a>>,
|
||||
@@ -288,6 +290,10 @@ pub async fn zo_config() -> Result<HttpResponse, Error> {
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect(),
|
||||
default_secondary_index_fields: SQL_SECONDARY_INDEX_SEARCH_FIELDS
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect(),
|
||||
default_quick_mode_fields: QUICK_MODEL_FIELDS.to_vec(),
|
||||
default_functions: DEFAULT_FUNCTIONS.to_vec(),
|
||||
sql_base64_enabled: cfg.common.ui_sql_base64_enabled,
|
||||
|
||||
+31
-42
@@ -689,7 +689,7 @@ async fn build_sql(
|
||||
let where_sql = conditions
|
||||
.to_sql(&schema)
|
||||
.await
|
||||
.map_err(|err| anyhow::anyhow!("Error building SQL on stream {}: {}", &stream_name, err))?;
|
||||
.map_err(|err| anyhow::anyhow!("Error building SQL on stream {stream_name}: {err}"))?;
|
||||
if query_condition.aggregation.is_none() {
|
||||
return Ok(format!("SELECT * FROM \"{stream_name}\" WHERE {where_sql}"));
|
||||
}
|
||||
@@ -702,9 +702,8 @@ async fn build_sql(
|
||||
Ok(field) => field.data_type(),
|
||||
Err(_) => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Aggregation column {} not found on stream {}",
|
||||
"Aggregation column {} not found on stream {stream_name}",
|
||||
&agg.having.column,
|
||||
&stream_name
|
||||
));
|
||||
}
|
||||
};
|
||||
@@ -766,17 +765,17 @@ fn build_expr(
|
||||
cond.value.to_string()
|
||||
};
|
||||
match cond.operator {
|
||||
Operator::EqualTo => format!("\"{}\" {} '{}'", field_alias, "=", val),
|
||||
Operator::NotEqualTo => format!("\"{}\" {} '{}'", field_alias, "!=", val),
|
||||
Operator::GreaterThan => format!("\"{}\" {} '{}'", field_alias, ">", val),
|
||||
Operator::EqualTo => format!("\"{field_alias}\" = '{val}'"),
|
||||
Operator::NotEqualTo => format!("\"{field_alias}\" != '{val}'"),
|
||||
Operator::GreaterThan => format!("\"{field_alias}\" > '{val}'"),
|
||||
Operator::GreaterThanEquals => {
|
||||
format!("\"{}\" {} '{}'", field_alias, ">=", val)
|
||||
format!("\"{field_alias}\" >= '{val}'")
|
||||
}
|
||||
Operator::LessThan => format!("\"{}\" {} '{}'", field_alias, "<", val),
|
||||
Operator::LessThanEquals => format!("\"{}\" {} '{}'", field_alias, "<=", val),
|
||||
Operator::Contains => format!("\"{}\" {} '%{}%'", field_alias, "LIKE", val),
|
||||
Operator::LessThan => format!("\"{field_alias}\" < '{val}'"),
|
||||
Operator::LessThanEquals => format!("\"{field_alias}\" <= '{val}'"),
|
||||
Operator::Contains => format!("str_match(\"{field_alias}\", '%{val}%')"),
|
||||
Operator::NotContains => {
|
||||
format!("\"{}\" {} '%{}%'", field_alias, "NOT LIKE", val)
|
||||
format!("\"{field_alias}\" NOT LIKE '%{val}%'")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -790,30 +789,27 @@ fn build_expr(
|
||||
.parse()
|
||||
.map_err(|e| {
|
||||
anyhow::anyhow!(
|
||||
"Column [{}] dataType is [{}] but value is [{}], err: {}",
|
||||
"Column [{}] dataType is [{field_type}] but value is [{}], err: {e}",
|
||||
cond.column,
|
||||
field_type,
|
||||
cond.value,
|
||||
e
|
||||
)
|
||||
})?
|
||||
};
|
||||
match cond.operator {
|
||||
Operator::EqualTo => format!("\"{}\" {} {}", field_alias, "=", val),
|
||||
Operator::NotEqualTo => format!("\"{}\" {} {}", field_alias, "!=", val),
|
||||
Operator::GreaterThan => format!("\"{}\" {} {}", field_alias, ">", val),
|
||||
Operator::EqualTo => format!("\"{field_alias}\" = {val}"),
|
||||
Operator::NotEqualTo => format!("\"{field_alias}\" != {val}"),
|
||||
Operator::GreaterThan => format!("\"{field_alias}\" > {val}"),
|
||||
Operator::GreaterThanEquals => {
|
||||
format!("\"{}\" {} {}", field_alias, ">=", val)
|
||||
format!("\"{field_alias}\" >= {val}")
|
||||
}
|
||||
Operator::LessThan => format!("\"{}\" {} {}", field_alias, "<", val),
|
||||
Operator::LessThan => format!("\"{field_alias}\" < {val}"),
|
||||
Operator::LessThanEquals => {
|
||||
format!("\"{}\" {} {}", field_alias, "<=", val)
|
||||
format!("\"{field_alias}\" <= {val}")
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Column {} has data_type [{}] and it does not supported operator [{:?}]",
|
||||
"Column {} has data_type [{field_type}] and it does not supported operator [{:?}]",
|
||||
cond.column,
|
||||
field_type,
|
||||
cond.operator
|
||||
));
|
||||
}
|
||||
@@ -829,30 +825,27 @@ fn build_expr(
|
||||
.parse()
|
||||
.map_err(|e| {
|
||||
anyhow::anyhow!(
|
||||
"Column [{}] dataType is [{}] but value is [{}], err: {}",
|
||||
"Column [{}] dataType is [{field_type}] but value is [{}], err: {e}",
|
||||
cond.column,
|
||||
field_type,
|
||||
cond.value,
|
||||
e
|
||||
)
|
||||
})?
|
||||
};
|
||||
match cond.operator {
|
||||
Operator::EqualTo => format!("\"{}\" {} {}", field_alias, "=", val),
|
||||
Operator::NotEqualTo => format!("\"{}\" {} {}", field_alias, "!=", val),
|
||||
Operator::GreaterThan => format!("\"{}\" {} {}", field_alias, ">", val),
|
||||
Operator::EqualTo => format!("\"{field_alias}\" = {val}"),
|
||||
Operator::NotEqualTo => format!("\"{field_alias}\" != {val}"),
|
||||
Operator::GreaterThan => format!("\"{field_alias}\" > {val}"),
|
||||
Operator::GreaterThanEquals => {
|
||||
format!("\"{}\" {} {}", field_alias, ">=", val)
|
||||
format!("\"{field_alias}\" >= {val}")
|
||||
}
|
||||
Operator::LessThan => format!("\"{}\" {} {}", field_alias, "<", val),
|
||||
Operator::LessThan => format!("\"{field_alias}\" < {val}"),
|
||||
Operator::LessThanEquals => {
|
||||
format!("\"{}\" {} {}", field_alias, "<=", val)
|
||||
format!("\"{field_alias}\" <= {val}")
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Column {} has data_type [{}] and it does not supported operator [{:?}]",
|
||||
"Column {} has data_type [{field_type}] and it does not supported operator [{:?}]",
|
||||
cond.column,
|
||||
field_type,
|
||||
cond.operator
|
||||
));
|
||||
}
|
||||
@@ -868,22 +861,19 @@ fn build_expr(
|
||||
.parse()
|
||||
.map_err(|e| {
|
||||
anyhow::anyhow!(
|
||||
"Column [{}] dataType is [{}] but value is [{}], err: {}",
|
||||
"Column [{}] dataType is [{field_type}] but value is [{}], err: {e}",
|
||||
cond.column,
|
||||
field_type,
|
||||
cond.value,
|
||||
e
|
||||
)
|
||||
})?
|
||||
};
|
||||
match cond.operator {
|
||||
Operator::EqualTo => format!("\"{}\" {} {}", field_alias, "=", val),
|
||||
Operator::NotEqualTo => format!("\"{}\" {} {}", field_alias, "!=", val),
|
||||
Operator::EqualTo => format!("\"{field_alias}\" = {val}"),
|
||||
Operator::NotEqualTo => format!("\"{field_alias}\" != {val}"),
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Column {} has data_type [{}] and it does not supported operator [{:?}]",
|
||||
"Column {} has data_type [{field_type}] and it does not supported operator [{:?}]",
|
||||
cond.column,
|
||||
field_type,
|
||||
cond.operator
|
||||
));
|
||||
}
|
||||
@@ -891,9 +881,8 @@ fn build_expr(
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Column {} has data_type [{}] and it does not supported by alert, if you think this is a bug please report it to us",
|
||||
"Column {} has data_type [{field_type}] and it does not supported by alert, if you think this is a bug please report it to us",
|
||||
cond.column,
|
||||
field_type
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user