mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-10-04 02:55:44 +00:00
fix(promql): resolve dotted column names as unqualified columns (#9391)
* fix(promql): resolve dotted column names as unqualified columns col(), From<&str>/From<String> for Column and string join keys go through Column::from_qualified_name, which splits `service.name` into relation `service` and column `name` and lowercases unquoted identifiers. Build PromQL column references with Column::from_name / ident() instead. Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * fix(servers): resolve remote read matcher labels as unqualified columns Signed-off-by: Dennis Zhuang <killme2008@gmail.com> * test(promql): cover same-name columns differing in case and without() Signed-off-by: Dennis Zhuang <killme2008@gmail.com> --------- Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
This commit is contained in:
@@ -34,7 +34,7 @@ use datafusion::physical_plan::{
|
||||
Partitioning, PhysicalExpr, PlanProperties, RecordBatchStream, SendableRecordBatchStream,
|
||||
};
|
||||
use datafusion_common::DFSchema;
|
||||
use datafusion_expr::{EmptyRelation, col};
|
||||
use datafusion_expr::{EmptyRelation, ident};
|
||||
use datatypes::arrow;
|
||||
use datatypes::arrow::array::{ArrayRef, Float64Array, TimestampMillisecondArray};
|
||||
use datatypes::arrow::datatypes::{DataType, Field, SchemaRef, TimeUnit};
|
||||
@@ -108,7 +108,7 @@ impl UserDefinedLogicalNodeCore for Absent {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
vec![col(&self.time_index_column)]
|
||||
vec![ident(&self.time_index_column)]
|
||||
}
|
||||
|
||||
fn necessary_children_exprs(&self, _output_columns: &[usize]) -> Option<Vec<Vec<usize>>> {
|
||||
|
||||
@@ -40,7 +40,7 @@ use datafusion::physical_plan::{
|
||||
SendableRecordBatchStream, StatisticsArgs,
|
||||
};
|
||||
use datafusion::physical_planner::PhysicalPlanner;
|
||||
use datafusion::prelude::{Expr, col, lit};
|
||||
use datafusion::prelude::{Expr, ident, lit};
|
||||
use datafusion_expr::LogicalPlanBuilder;
|
||||
use datatypes::arrow::array::TimestampMillisecondArray;
|
||||
use datatypes::arrow::datatypes::SchemaRef;
|
||||
@@ -409,7 +409,7 @@ fn build_ts_only_schema(column_name: &str) -> DFSchema {
|
||||
pub fn build_special_time_expr(time_index_column_name: &str) -> Expr {
|
||||
let input_schema = build_ts_only_schema(time_index_column_name);
|
||||
// safety: should not failed (UT covers this)
|
||||
col(time_index_column_name)
|
||||
ident(time_index_column_name)
|
||||
.cast_to(&DataType::Int64, &input_schema)
|
||||
.unwrap()
|
||||
.cast_to(&DataType::Float64, &input_schema)
|
||||
|
||||
@@ -41,7 +41,7 @@ use datafusion::physical_plan::{
|
||||
SendableRecordBatchStream, StatisticsArgs,
|
||||
};
|
||||
use datafusion::prelude::{Column, Expr};
|
||||
use datafusion_expr::{EmptyRelation, col};
|
||||
use datafusion_expr::{EmptyRelation, ident};
|
||||
use datatypes::arrow_array::string_array_value_at_index;
|
||||
use datatypes::prelude::{ConcreteDataType, DataType as GtDataType};
|
||||
use datatypes::value::{OrderedF64, Value, ValueRef};
|
||||
@@ -141,14 +141,14 @@ impl UserDefinedLogicalNodeCore for HistogramFold {
|
||||
}
|
||||
|
||||
let mut exprs = vec![
|
||||
col(&self.le_column),
|
||||
col(&self.ts_column),
|
||||
col(&self.field_column),
|
||||
ident(&self.le_column),
|
||||
ident(&self.ts_column),
|
||||
ident(&self.field_column),
|
||||
];
|
||||
exprs.extend(self.input.schema().fields().iter().filter_map(|f| {
|
||||
let name = f.name();
|
||||
if name != &self.le_column && name != &self.ts_column && name != &self.field_column {
|
||||
Some(col(name))
|
||||
Some(ident(name))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ use datafusion::physical_plan::{
|
||||
PhysicalExpr, PlanProperties, RecordBatchStream, SendableRecordBatchStream, Statistics,
|
||||
StatisticsArgs,
|
||||
};
|
||||
use datafusion_expr::col;
|
||||
use datafusion_expr::ident;
|
||||
use datatypes::arrow::compute;
|
||||
use datatypes::timestamp::timestamp_array_to_primitive;
|
||||
use futures::{Stream, StreamExt, ready};
|
||||
@@ -140,8 +140,8 @@ impl UserDefinedLogicalNodeCore for InstantManipulate {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let mut exprs = vec![col(&self.time_index_column)];
|
||||
exprs.extend(self.staleness_field_columns().map(col));
|
||||
let mut exprs = vec![ident(&self.time_index_column)];
|
||||
exprs.extend(self.staleness_field_columns().map(ident));
|
||||
exprs
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ use datafusion::physical_plan::{
|
||||
InputDistributionRequirements, PhysicalExpr, PlanProperties, RecordBatchStream,
|
||||
SendableRecordBatchStream, StatisticsArgs,
|
||||
};
|
||||
use datafusion_expr::col;
|
||||
use datafusion_expr::ident;
|
||||
use datatypes::arrow::array::TimestampMillisecondArray;
|
||||
use datatypes::arrow::datatypes::{SchemaRef, TimestampMillisecondType};
|
||||
use datatypes::arrow::record_batch::RecordBatch;
|
||||
@@ -93,8 +93,8 @@ impl UserDefinedLogicalNodeCore for SeriesNormalize {
|
||||
|
||||
self.tag_columns
|
||||
.iter()
|
||||
.map(col)
|
||||
.chain(std::iter::once(col(&self.time_index_column_name)))
|
||||
.map(ident)
|
||||
.chain(std::iter::once(ident(&self.time_index_column_name)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ use datafusion::physical_plan::{
|
||||
InputDistributionRequirements, PhysicalExpr, PlanProperties, RecordBatchStream,
|
||||
SendableRecordBatchStream, Statistics, StatisticsArgs,
|
||||
};
|
||||
use datafusion_expr::col;
|
||||
use datafusion_expr::ident;
|
||||
use datatypes::timestamp::timestamp_array_to_primitive;
|
||||
use futures::{Stream, StreamExt, ready};
|
||||
use greptime_proto::substrait_extension as pb;
|
||||
@@ -318,8 +318,8 @@ impl UserDefinedLogicalNodeCore for RangeManipulate {
|
||||
}
|
||||
|
||||
let mut exprs = Vec::with_capacity(1 + self.field_columns.len());
|
||||
exprs.push(col(&self.time_index));
|
||||
exprs.extend(self.field_columns.iter().map(col));
|
||||
exprs.push(ident(&self.time_index));
|
||||
exprs.extend(self.field_columns.iter().map(ident));
|
||||
exprs
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ use datafusion::physical_plan::{
|
||||
SendableRecordBatchStream, StatisticsArgs,
|
||||
};
|
||||
use datafusion::prelude::Expr;
|
||||
use datafusion_expr::col;
|
||||
use datafusion_expr::ident;
|
||||
use datatypes::arrow::array::{Array, ArrayRef, Float64Array, TimestampMillisecondArray};
|
||||
use datatypes::arrow::compute::{CastOptions, cast_with_options, concat_batches};
|
||||
use datatypes::arrow::datatypes::{DataType, Field, Schema, SchemaRef, TimeUnit};
|
||||
@@ -282,9 +282,9 @@ impl UserDefinedLogicalNodeCore for ScalarCalculate {
|
||||
|
||||
self.tag_columns
|
||||
.iter()
|
||||
.map(col)
|
||||
.chain(std::iter::once(col(&self.time_index)))
|
||||
.chain(std::iter::once(col(&self.field_column)))
|
||||
.map(ident)
|
||||
.chain(std::iter::once(ident(&self.time_index)))
|
||||
.chain(std::iter::once(ident(&self.field_column)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ use datafusion::physical_plan::{
|
||||
DisplayAs, DisplayFormatType, Distribution, ExecutionPlan, InputDistributionRequirements,
|
||||
PhysicalExpr, PlanProperties, RecordBatchStream, SendableRecordBatchStream,
|
||||
};
|
||||
use datafusion_expr::col;
|
||||
use datafusion_expr::ident;
|
||||
use datatypes::arrow::compute;
|
||||
use datatypes::arrow_array::string_array_value_at_index;
|
||||
use datatypes::compute::SortOptions;
|
||||
@@ -186,8 +186,8 @@ impl UserDefinedLogicalNodeCore for SeriesDivide {
|
||||
|
||||
self.tag_columns
|
||||
.iter()
|
||||
.map(col)
|
||||
.chain(std::iter::once(col(&self.time_index_column)))
|
||||
.map(ident)
|
||||
.chain(std::iter::once(ident(&self.time_index_column)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ use datafusion::physical_plan::{
|
||||
Partitioning, PhysicalExpr, PlanProperties, RecordBatchStream, SendableRecordBatchStream,
|
||||
hash_utils,
|
||||
};
|
||||
use datafusion_expr::col;
|
||||
use datafusion_expr::ident;
|
||||
use datatypes::arrow::compute;
|
||||
use futures::{Stream, StreamExt, ready};
|
||||
use greptime_proto::substrait_extension as pb;
|
||||
@@ -278,12 +278,12 @@ impl UserDefinedLogicalNodeCore for UnionDistinctOn {
|
||||
let mut exprs = self
|
||||
.compare_key_indices
|
||||
.iter()
|
||||
.filter_map(|index| fields.get(*index).map(|field| col(field.name())))
|
||||
.filter_map(|index| fields.get(*index).map(|field| ident(field.name())))
|
||||
.collect::<Vec<_>>();
|
||||
if !self.compare_key_indices.contains(&self.ts_col_idx)
|
||||
&& let Some(field) = fields.get(self.ts_col_idx)
|
||||
{
|
||||
exprs.push(col(field.name()));
|
||||
exprs.push(ident(field.name()));
|
||||
}
|
||||
exprs
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ use datafusion_common::{DFSchema, NullEquality, TableReference};
|
||||
use datafusion_expr::expr::WindowFunctionParams;
|
||||
use datafusion_expr::expr_fn::when;
|
||||
use datafusion_expr::utils::{conjunction, disjunction};
|
||||
use datafusion_expr::{ExprSchemable, Literal, SortExpr, TableSource, col, lit};
|
||||
use datafusion_expr::{ExprSchemable, Literal, SortExpr, TableSource, ident, lit};
|
||||
use datafusion_functions::core::coalesce;
|
||||
use datatypes::arrow::datatypes::{DataType as ArrowDataType, TimeUnit as ArrowTimeUnit};
|
||||
use datatypes::data_type::{ConcreteDataType, DataType as GreptimeDataType};
|
||||
@@ -678,7 +678,7 @@ impl PromPlanner {
|
||||
.cloned()
|
||||
.chain(prev_field_exprs.clone())
|
||||
.collect::<Vec<_>>();
|
||||
group_exprs.push(col(label));
|
||||
group_exprs.push(ident(label));
|
||||
let project_fields = self
|
||||
.create_field_column_exprs()?
|
||||
.into_iter()
|
||||
@@ -798,10 +798,10 @@ impl PromPlanner {
|
||||
),
|
||||
self.promql_annotations.clone(),
|
||||
)),
|
||||
args: vec![col(&histogram_column)],
|
||||
args: vec![ident(&histogram_column)],
|
||||
});
|
||||
let keep_float = when(col(&histogram_column).is_not_null(), drop_histogram)
|
||||
.otherwise(col(&float_column).is_not_null())
|
||||
let keep_float = when(ident(&histogram_column).is_not_null(), drop_histogram)
|
||||
.otherwise(ident(&float_column).is_not_null())
|
||||
.context(DataFusionPlanningSnafu)?;
|
||||
input = LogicalPlanBuilder::from(input)
|
||||
.filter(keep_float)
|
||||
@@ -852,7 +852,7 @@ impl PromPlanner {
|
||||
.iter()
|
||||
.fold(None, |expr, rank| {
|
||||
let predicate = DfExpr::BinaryExpr(BinaryExpr {
|
||||
left: Box::new(col(rank)),
|
||||
left: Box::new(ident(rank)),
|
||||
op: Operator::LtEq,
|
||||
right: Box::new(val.clone()),
|
||||
});
|
||||
@@ -868,7 +868,7 @@ impl PromPlanner {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let rank_columns: Vec<_> = rank_columns.into_iter().map(col).collect();
|
||||
let rank_columns: Vec<_> = rank_columns.into_iter().map(ident).collect();
|
||||
|
||||
let mut new_group_exprs = group_exprs.clone();
|
||||
// Order by ranks
|
||||
@@ -921,10 +921,12 @@ impl PromPlanner {
|
||||
if Self::field_column_is_native_histogram(&input_schema, col) {
|
||||
Ok(DfExpr::ScalarFunction(ScalarFunction {
|
||||
func: Arc::new(NativeHistogramNeg::scalar_udf()),
|
||||
args: vec![DfExpr::Column(col.into())],
|
||||
args: vec![DfExpr::Column(Column::from_name(col))],
|
||||
}))
|
||||
} else {
|
||||
Ok(DfExpr::Negative(Box::new(DfExpr::Column(col.into()))))
|
||||
Ok(DfExpr::Negative(Box::new(DfExpr::Column(
|
||||
Column::from_name(col),
|
||||
))))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1034,7 +1036,7 @@ impl PromPlanner {
|
||||
let binary_expr_builder = Self::prom_token_to_binary_expr_builder(*op)?;
|
||||
let rhs_is_histogram =
|
||||
Self::field_column_is_native_histogram(&input_schema, col);
|
||||
let rhs = DfExpr::Column(col.into());
|
||||
let rhs = DfExpr::Column(Column::from_name(col));
|
||||
let mut binary_expr = match Self::native_histogram_binary_expr(
|
||||
*op,
|
||||
expr.clone(),
|
||||
@@ -1101,7 +1103,7 @@ impl PromPlanner {
|
||||
let binary_expr_builder = Self::prom_token_to_binary_expr_builder(*op)?;
|
||||
let lhs_is_histogram =
|
||||
Self::field_column_is_native_histogram(&input_schema, col);
|
||||
let lhs = DfExpr::Column(col.into());
|
||||
let lhs = DfExpr::Column(Column::from_name(col));
|
||||
let mut binary_expr = match Self::native_histogram_binary_expr(
|
||||
*op,
|
||||
lhs.clone(),
|
||||
@@ -1753,7 +1755,7 @@ impl PromPlanner {
|
||||
// `timestamp()` preserves the shifted selector timeline even though
|
||||
// SeriesNormalize now retains raw native timestamp storage. Decimal
|
||||
// arithmetic shifts before truncating to milliseconds.
|
||||
let unit_factor = match col(&time_index_column)
|
||||
let unit_factor = match ident(&time_index_column)
|
||||
.get_type(normalize.schema())
|
||||
.context(DataFusionPlanningSnafu)?
|
||||
{
|
||||
@@ -1763,7 +1765,7 @@ impl PromPlanner {
|
||||
ArrowDataType::Timestamp(ArrowTimeUnit::Nanosecond, _) => (1, 7, 6),
|
||||
_ => unreachable!("time index is a timestamp"),
|
||||
};
|
||||
let sample_time = col(&time_index_column)
|
||||
let sample_time = ident(&time_index_column)
|
||||
.cast_to(&ArrowDataType::Int64, normalize.schema())
|
||||
.context(DataFusionPlanningSnafu)?
|
||||
.cast_to(&ArrowDataType::Decimal128(19, 0), normalize.schema())
|
||||
@@ -1877,7 +1879,7 @@ impl PromPlanner {
|
||||
input: LogicalPlan,
|
||||
timestamp_value_column: &str,
|
||||
) -> Result<LogicalPlan> {
|
||||
let time_expr = col(timestamp_value_column).alias(DEFAULT_FIELD_COLUMN);
|
||||
let time_expr = ident(timestamp_value_column).alias(DEFAULT_FIELD_COLUMN);
|
||||
self.ctx.field_columns = vec![time_expr.schema_name().to_string()];
|
||||
let mut project_exprs = Vec::with_capacity(self.ctx.tag_columns.len() + 2);
|
||||
project_exprs.push(self.create_time_index_column_expr()?);
|
||||
@@ -2507,7 +2509,7 @@ impl PromPlanner {
|
||||
// collect remaining fields and convert to col expr
|
||||
let mut exprs = all_fields
|
||||
.into_iter()
|
||||
.map(|c| DfExpr::Column(Column::from(c)))
|
||||
.map(|c| DfExpr::Column(Column::from_name(c)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// add timestamp column
|
||||
@@ -4774,7 +4776,7 @@ impl PromPlanner {
|
||||
.map(|col| {
|
||||
let mut sort_exprs = Vec::with_capacity(self.ctx.tag_columns.len() + 1);
|
||||
// Order by value in the specific order
|
||||
sort_exprs.push(DfExpr::Column(Column::from(col)).sort(asc, true));
|
||||
sort_exprs.push(DfExpr::Column(Column::from_name(col)).sort(asc, true));
|
||||
// Then tags if the values are equal,
|
||||
// Try to ensure the relative stability of the output results.
|
||||
sort_exprs.extend(tag_sort_exprs.clone());
|
||||
@@ -5547,7 +5549,7 @@ impl PromPlanner {
|
||||
.collect::<Vec<_>>();
|
||||
let assert_expr = DfExpr::ScalarFunction(ScalarFunction {
|
||||
func: Arc::new(UniqueMatchGroup::scalar_udf(group_labels, violation)),
|
||||
args: std::iter::once(col(count_column.as_str()))
|
||||
args: std::iter::once(ident(count_column.as_str()))
|
||||
.chain(group_exprs)
|
||||
.collect(),
|
||||
});
|
||||
@@ -6186,7 +6188,7 @@ impl PromPlanner {
|
||||
/// Generate an expr like `date_part("hour", <TIME_INDEX>)`. Caller should ensure the
|
||||
/// time index column in context is set
|
||||
fn date_part_on_time_index(&self, date_part: &str) -> Result<DfExpr> {
|
||||
let input_expr = datafusion::logical_expr::col(
|
||||
let input_expr = datafusion::logical_expr::ident(
|
||||
self.ctx
|
||||
.time_index_column
|
||||
.as_ref()
|
||||
|
||||
@@ -28,7 +28,7 @@ use datafusion::scalar::ScalarValue;
|
||||
use datafusion_common::DFSchema;
|
||||
use datafusion_expr::expr_fn::when;
|
||||
use datafusion_expr::simplify::SimplifyContext;
|
||||
use datafusion_expr::{col, lit};
|
||||
use datafusion_expr::{ident, lit};
|
||||
use datafusion_functions::core::coalesce;
|
||||
use datatypes::arrow::datatypes::DataType as ArrowDataType;
|
||||
use promql::extension_plan::{
|
||||
@@ -253,12 +253,12 @@ impl PromPlanner {
|
||||
"vector contains a mix of classic and native histograms".to_string(),
|
||||
self.promql_annotations.clone(),
|
||||
)),
|
||||
args: vec![col(&float_field), col(&histogram_field)],
|
||||
args: vec![ident(&float_field), ident(&histogram_field)],
|
||||
});
|
||||
let keep = when(
|
||||
col(&float_field)
|
||||
ident(&float_field)
|
||||
.is_not_null()
|
||||
.and(col(&histogram_field).is_not_null()),
|
||||
.and(ident(&histogram_field).is_not_null()),
|
||||
record_collision,
|
||||
)
|
||||
.otherwise(lit(true))
|
||||
@@ -268,7 +268,7 @@ impl PromPlanner {
|
||||
let output_field = native_expr.schema_name().to_string();
|
||||
let value = DfExpr::ScalarFunction(ScalarFunction {
|
||||
func: coalesce(),
|
||||
args: vec![col(&float_field), native_expr],
|
||||
args: vec![ident(&float_field), native_expr],
|
||||
});
|
||||
self.ctx.field_columns = vec![output_field.clone()];
|
||||
LogicalPlanBuilder::from(LogicalPlan::Extension(Extension {
|
||||
@@ -277,9 +277,9 @@ impl PromPlanner {
|
||||
.filter(keep)
|
||||
.context(DataFusionPlanningSnafu)?
|
||||
.project(
|
||||
std::iter::once(col(&time_index_column))
|
||||
std::iter::once(ident(&time_index_column))
|
||||
.chain(std::iter::once(value.alias(output_field)))
|
||||
.chain(tag_columns.iter().map(col)),
|
||||
.chain(tag_columns.iter().map(ident)),
|
||||
)
|
||||
.context(DataFusionPlanningSnafu)?
|
||||
.build()
|
||||
|
||||
@@ -764,6 +764,7 @@ impl PromPlanner {
|
||||
let join_keys = left_tag_col_set
|
||||
.into_iter()
|
||||
.chain([left_time_index])
|
||||
.map(Column::from_name)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ensure!(
|
||||
|
||||
@@ -36,7 +36,7 @@ use datafusion::datasource::memory::MemorySourceConfig;
|
||||
use datafusion::datasource::source::DataSourceExec;
|
||||
use datafusion::datasource::{MemTable, provider_as_source};
|
||||
use datafusion::execution::context::SessionContext;
|
||||
use datafusion::logical_expr::Extension;
|
||||
use datafusion::logical_expr::{Extension, col};
|
||||
use datatypes::prelude::ConcreteDataType;
|
||||
use datatypes::schema::{ColumnSchema, Schema};
|
||||
use promql::extension_plan::HistogramFold;
|
||||
@@ -1210,8 +1210,10 @@ fn classic_and_native_histogram_table_provider(
|
||||
let table_name = "mixed_histogram";
|
||||
let catalog = MemoryCatalogManager::with_default_setup();
|
||||
let schema = Arc::new(Schema::new(vec![
|
||||
// A dotted tag name guards the mixed histogram_quantile projection
|
||||
// against qualified-name parsing (#9390).
|
||||
ColumnSchema::new(
|
||||
"tag".to_string(),
|
||||
"service.name".to_string(),
|
||||
ConcreteDataType::string_datatype(),
|
||||
false,
|
||||
),
|
||||
@@ -4386,7 +4388,7 @@ async fn mixed_histogram_helpers_execute_classic_and_native_samples() {
|
||||
.iter()
|
||||
.flat_map(|batch| {
|
||||
let tags = batch
|
||||
.column_by_name("tag")
|
||||
.column_by_name("service.name")
|
||||
.unwrap()
|
||||
.as_any()
|
||||
.downcast_ref::<StringArray>()
|
||||
|
||||
@@ -36,7 +36,7 @@ use common_query::prelude::{greptime_timestamp, greptime_value};
|
||||
use common_recordbatch::{RecordBatch, RecordBatches};
|
||||
use common_telemetry::{tracing, warn};
|
||||
use datafusion::dataframe::DataFrame;
|
||||
use datafusion::prelude::{Expr, col, lit, regexp_match};
|
||||
use datafusion::prelude::{Expr, ident, lit, regexp_match};
|
||||
use datafusion_common::ScalarValue;
|
||||
use datafusion_expr::LogicalPlan;
|
||||
use snafu::{OptionExt, ResultExt, ensure};
|
||||
@@ -150,8 +150,9 @@ pub fn query_to_plan(
|
||||
let mut conditions = Vec::with_capacity(label_matches.len() + 1);
|
||||
|
||||
conditions
|
||||
.push(col(timestamp_column_name).gt_eq(lit_timestamp_millisecond(start_timestamp_ms)));
|
||||
conditions.push(col(timestamp_column_name).lt_eq(lit_timestamp_millisecond(end_timestamp_ms)));
|
||||
.push(ident(timestamp_column_name).gt_eq(lit_timestamp_millisecond(start_timestamp_ms)));
|
||||
conditions
|
||||
.push(ident(timestamp_column_name).lt_eq(lit_timestamp_millisecond(end_timestamp_ms)));
|
||||
|
||||
for m in label_matches {
|
||||
let name = &m.name;
|
||||
@@ -170,18 +171,18 @@ pub fn query_to_plan(
|
||||
|
||||
match m_type {
|
||||
MatcherType::Eq => {
|
||||
conditions.push(col(name).eq(lit(value)));
|
||||
conditions.push(ident(name).eq(lit(value)));
|
||||
}
|
||||
MatcherType::Neq => {
|
||||
conditions.push(col(name).not_eq(lit(value)));
|
||||
conditions.push(ident(name).not_eq(lit(value)));
|
||||
}
|
||||
// Case sensitive regexp match
|
||||
MatcherType::Re => {
|
||||
conditions.push(regexp_match(col(name), lit(value), None).is_not_null());
|
||||
conditions.push(regexp_match(ident(name), lit(value), None).is_not_null());
|
||||
}
|
||||
// Case sensitive regexp not match
|
||||
MatcherType::Nre => {
|
||||
conditions.push(regexp_match(col(name), lit(value), None).is_null());
|
||||
conditions.push(regexp_match(ident(name), lit(value), None).is_null());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -890,6 +891,8 @@ mod tests {
|
||||
ColumnSchema::new(greptime_value(), ConcreteDataType::float64_datatype(), true),
|
||||
ColumnSchema::new("instance", ConcreteDataType::string_datatype(), true),
|
||||
ColumnSchema::new("job", ConcreteDataType::string_datatype(), true),
|
||||
ColumnSchema::new("service.name", ConcreteDataType::string_datatype(), true),
|
||||
ColumnSchema::new("Region", ConcreteDataType::string_datatype(), true),
|
||||
]));
|
||||
let recordbatch = RecordBatch::new(
|
||||
schema,
|
||||
@@ -898,6 +901,8 @@ mod tests {
|
||||
Arc::new(Float64Vector::from_vec(vec![3.0])) as _,
|
||||
Arc::new(StringVector::from(vec!["host1"])) as _,
|
||||
Arc::new(StringVector::from(vec!["job"])) as _,
|
||||
Arc::new(StringVector::from(vec!["api"])) as _,
|
||||
Arc::new(StringVector::from(vec!["us"])) as _,
|
||||
],
|
||||
)
|
||||
.unwrap();
|
||||
@@ -936,6 +941,16 @@ mod tests {
|
||||
value: "localhost".to_string(),
|
||||
r#type: NEQ_TYPE,
|
||||
},
|
||||
LabelMatcher {
|
||||
name: "service.name".to_string(),
|
||||
value: "api".to_string(),
|
||||
r#type: EQ_TYPE,
|
||||
},
|
||||
LabelMatcher {
|
||||
name: "Region".to_string(),
|
||||
value: "us".to_string(),
|
||||
r#type: EQ_TYPE,
|
||||
},
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
@@ -946,7 +961,7 @@ mod tests {
|
||||
|
||||
let ts_col = greptime_timestamp();
|
||||
let expected = format!(
|
||||
"Filter: ?table?.{} >= TimestampMillisecond(1000, None) AND ?table?.{} <= TimestampMillisecond(2000, None) AND regexp_match(?table?.job, Utf8(\"*prom*\")) IS NOT NULL AND ?table?.instance != Utf8(\"localhost\")\n TableScan: ?table?",
|
||||
"Filter: ?table?.{} >= TimestampMillisecond(1000, None) AND ?table?.{} <= TimestampMillisecond(2000, None) AND regexp_match(?table?.job, Utf8(\"*prom*\")) IS NOT NULL AND ?table?.instance != Utf8(\"localhost\") AND ?table?.service.name = Utf8(\"api\") AND ?table?.Region = Utf8(\"us\")\n TableScan: ?table?",
|
||||
ts_col, ts_col
|
||||
);
|
||||
assert_eq!(expected, display_string);
|
||||
|
||||
@@ -0,0 +1,505 @@
|
||||
-- https://github.com/GreptimeTeam/greptimedb/issues/9390
|
||||
-- Tag, field and time index names containing dots or upper case letters must
|
||||
-- be resolved as plain column names, not as `relation.column`. `Host` and `host`
|
||||
-- hold different values, so reading one for the other changes the output.
|
||||
CREATE TABLE "otel.m" (
|
||||
"ts.time" TIMESTAMP(3) TIME INDEX,
|
||||
"service.name" STRING,
|
||||
"Host" STRING,
|
||||
host STRING,
|
||||
"v.val" DOUBLE,
|
||||
PRIMARY KEY ("service.name", "Host", host)
|
||||
) PARTITION ON COLUMNS ("service.name") (
|
||||
"service.name" < 'b',
|
||||
"service.name" >= 'b'
|
||||
);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
INSERT INTO "otel.m" VALUES
|
||||
(0, 'a', 'h1', 'x', 1),
|
||||
(0, 'a', 'h2', 'x', 2),
|
||||
(0, 'b', 'h1', 'y', 3),
|
||||
(5000, 'a', 'h1', 'x', 4),
|
||||
(5000, 'a', 'h2', 'x', 5),
|
||||
(5000, 'b', 'h1', 'y', 6),
|
||||
(10000, 'a', 'h1', 'x', 8),
|
||||
(10000, 'a', 'h2', 'x', 9),
|
||||
(10000, 'b', 'h1', 'y', 8);
|
||||
|
||||
Affected Rows: 9
|
||||
|
||||
CREATE TABLE "otel.h" (
|
||||
"ts.time" TIMESTAMP(3) TIME INDEX,
|
||||
"service.name" STRING,
|
||||
le STRING,
|
||||
"v.val" DOUBLE,
|
||||
PRIMARY KEY ("service.name", le)
|
||||
);
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
INSERT INTO "otel.h" VALUES
|
||||
(0, 'a', '0.1', 1),
|
||||
(0, 'a', '1', 3),
|
||||
(0, 'a', '+Inf', 4),
|
||||
(10000, 'a', '0.1', 2),
|
||||
(10000, 'a', '1', 6),
|
||||
(10000, 'a', '+Inf', 10);
|
||||
|
||||
Affected Rows: 6
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} and {"otel.m", "Host"="h1"};
|
||||
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| ts.time | service.name | Host | host | v.val |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| 1970-01-01T00:00:00 | a | h1 | x | 1.0 |
|
||||
| 1970-01-01T00:00:00 | b | h1 | y | 3.0 |
|
||||
| 1970-01-01T00:00:05 | a | h1 | x | 4.0 |
|
||||
| 1970-01-01T00:00:05 | b | h1 | y | 6.0 |
|
||||
| 1970-01-01T00:00:10 | a | h1 | x | 8.0 |
|
||||
| 1970-01-01T00:00:10 | b | h1 | y | 8.0 |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} and on("service.name") {"otel.m", "service.name"="b"};
|
||||
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| ts.time | service.name | Host | host | v.val |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| 1970-01-01T00:00:00 | b | h1 | y | 3.0 |
|
||||
| 1970-01-01T00:00:05 | b | h1 | y | 6.0 |
|
||||
| 1970-01-01T00:00:10 | b | h1 | y | 8.0 |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} and on(host) {"otel.m", host="y"};
|
||||
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| ts.time | service.name | Host | host | v.val |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| 1970-01-01T00:00:00 | b | h1 | y | 3.0 |
|
||||
| 1970-01-01T00:00:05 | b | h1 | y | 6.0 |
|
||||
| 1970-01-01T00:00:10 | b | h1 | y | 8.0 |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} unless {"otel.m", "Host"="h1"};
|
||||
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| ts.time | service.name | Host | host | v.val |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| 1970-01-01T00:00:00 | a | h2 | x | 2.0 |
|
||||
| 1970-01-01T00:00:05 | a | h2 | x | 5.0 |
|
||||
| 1970-01-01T00:00:10 | a | h2 | x | 9.0 |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} unless on("service.name") {"otel.m", "service.name"="b"};
|
||||
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| ts.time | service.name | Host | host | v.val |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
| 1970-01-01T00:00:00 | a | h1 | x | 1.0 |
|
||||
| 1970-01-01T00:00:00 | a | h2 | x | 2.0 |
|
||||
| 1970-01-01T00:00:05 | a | h1 | x | 4.0 |
|
||||
| 1970-01-01T00:00:05 | a | h2 | x | 5.0 |
|
||||
| 1970-01-01T00:00:10 | a | h1 | x | 8.0 |
|
||||
| 1970-01-01T00:00:10 | a | h2 | x | 9.0 |
|
||||
+---------------------+--------------+------+------+-------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} or {"otel.m", "Host"="h1"};
|
||||
|
||||
+---------------------+------+------+--------------+-------+
|
||||
| ts.time | Host | host | service.name | v.val |
|
||||
+---------------------+------+------+--------------+-------+
|
||||
| 1970-01-01T00:00:00 | h1 | x | a | 1.0 |
|
||||
| 1970-01-01T00:00:00 | h1 | y | b | 3.0 |
|
||||
| 1970-01-01T00:00:00 | h2 | x | a | 2.0 |
|
||||
| 1970-01-01T00:00:05 | h1 | x | a | 4.0 |
|
||||
| 1970-01-01T00:00:05 | h1 | y | b | 6.0 |
|
||||
| 1970-01-01T00:00:05 | h2 | x | a | 5.0 |
|
||||
| 1970-01-01T00:00:10 | h1 | x | a | 8.0 |
|
||||
| 1970-01-01T00:00:10 | h1 | y | b | 8.0 |
|
||||
| 1970-01-01T00:00:10 | h2 | x | a | 9.0 |
|
||||
+---------------------+------+------+--------------+-------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') count_values("v.name", {"otel.m"});
|
||||
|
||||
+---------------------+---------------------+--------+
|
||||
| count(otel.m.v.val) | ts.time | v.name |
|
||||
+---------------------+---------------------+--------+
|
||||
| 1 | 1970-01-01T00:00:00 | 1 |
|
||||
| 1 | 1970-01-01T00:00:00 | 2 |
|
||||
| 1 | 1970-01-01T00:00:00 | 3 |
|
||||
| 1 | 1970-01-01T00:00:05 | 4 |
|
||||
| 1 | 1970-01-01T00:00:05 | 5 |
|
||||
| 1 | 1970-01-01T00:00:05 | 6 |
|
||||
| 1 | 1970-01-01T00:00:10 | 9 |
|
||||
| 2 | 1970-01-01T00:00:10 | 8 |
|
||||
+---------------------+---------------------+--------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') count_values by ("service.name") ("v.name", {"otel.m"});
|
||||
|
||||
+---------------------+--------------+---------------------+--------+
|
||||
| count(otel.m.v.val) | service.name | ts.time | v.name |
|
||||
+---------------------+--------------+---------------------+--------+
|
||||
| 1 | a | 1970-01-01T00:00:00 | 1 |
|
||||
| 1 | a | 1970-01-01T00:00:00 | 2 |
|
||||
| 1 | a | 1970-01-01T00:00:05 | 4 |
|
||||
| 1 | a | 1970-01-01T00:00:05 | 5 |
|
||||
| 1 | a | 1970-01-01T00:00:10 | 8 |
|
||||
| 1 | a | 1970-01-01T00:00:10 | 9 |
|
||||
| 1 | b | 1970-01-01T00:00:00 | 3 |
|
||||
| 1 | b | 1970-01-01T00:00:05 | 6 |
|
||||
| 1 | b | 1970-01-01T00:00:10 | 8 |
|
||||
+---------------------+--------------+---------------------+--------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') topk(1, {"otel.m"});
|
||||
|
||||
+-------+--------------+------+------+---------------------+
|
||||
| v.val | service.name | Host | host | ts.time |
|
||||
+-------+--------------+------+------+---------------------+
|
||||
| 3.0 | b | h1 | y | 1970-01-01T00:00:00 |
|
||||
| 6.0 | b | h1 | y | 1970-01-01T00:00:05 |
|
||||
| 9.0 | a | h2 | x | 1970-01-01T00:00:10 |
|
||||
+-------+--------------+------+------+---------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') bottomk by ("service.name") (1, {"otel.m"});
|
||||
|
||||
+-------+--------------+------+------+---------------------+
|
||||
| v.val | service.name | Host | host | ts.time |
|
||||
+-------+--------------+------+------+---------------------+
|
||||
| 1.0 | a | h1 | x | 1970-01-01T00:00:00 |
|
||||
| 3.0 | b | h1 | y | 1970-01-01T00:00:00 |
|
||||
| 4.0 | a | h1 | x | 1970-01-01T00:00:05 |
|
||||
| 6.0 | b | h1 | y | 1970-01-01T00:00:05 |
|
||||
| 8.0 | a | h1 | x | 1970-01-01T00:00:10 |
|
||||
| 8.0 | b | h1 | y | 1970-01-01T00:00:10 |
|
||||
+-------+--------------+------+------+---------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum by ("service.name") ({"otel.m"});
|
||||
|
||||
+--------------+---------------------+-------------------+
|
||||
| service.name | ts.time | sum(otel.m.v.val) |
|
||||
+--------------+---------------------+-------------------+
|
||||
| a | 1970-01-01T00:00:00 | 3.0 |
|
||||
| a | 1970-01-01T00:00:05 | 9.0 |
|
||||
| a | 1970-01-01T00:00:10 | 17.0 |
|
||||
| b | 1970-01-01T00:00:00 | 3.0 |
|
||||
| b | 1970-01-01T00:00:05 | 6.0 |
|
||||
| b | 1970-01-01T00:00:10 | 8.0 |
|
||||
+--------------+---------------------+-------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum by ("Host") ({"otel.m"});
|
||||
|
||||
+------+---------------------+-------------------+
|
||||
| Host | ts.time | sum(otel.m.v.val) |
|
||||
+------+---------------------+-------------------+
|
||||
| h1 | 1970-01-01T00:00:00 | 4.0 |
|
||||
| h1 | 1970-01-01T00:00:05 | 10.0 |
|
||||
| h1 | 1970-01-01T00:00:10 | 16.0 |
|
||||
| h2 | 1970-01-01T00:00:00 | 2.0 |
|
||||
| h2 | 1970-01-01T00:00:05 | 5.0 |
|
||||
| h2 | 1970-01-01T00:00:10 | 9.0 |
|
||||
+------+---------------------+-------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum by (host) ({"otel.m"});
|
||||
|
||||
+------+---------------------+-------------------+
|
||||
| host | ts.time | sum(otel.m.v.val) |
|
||||
+------+---------------------+-------------------+
|
||||
| x | 1970-01-01T00:00:00 | 3.0 |
|
||||
| x | 1970-01-01T00:00:05 | 9.0 |
|
||||
| x | 1970-01-01T00:00:10 | 17.0 |
|
||||
| y | 1970-01-01T00:00:00 | 3.0 |
|
||||
| y | 1970-01-01T00:00:05 | 6.0 |
|
||||
| y | 1970-01-01T00:00:10 | 8.0 |
|
||||
+------+---------------------+-------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum without ("Host") ({"otel.m"});
|
||||
|
||||
+------+--------------+---------------------+-------------------+
|
||||
| host | service.name | ts.time | sum(otel.m.v.val) |
|
||||
+------+--------------+---------------------+-------------------+
|
||||
| x | a | 1970-01-01T00:00:00 | 3.0 |
|
||||
| x | a | 1970-01-01T00:00:05 | 9.0 |
|
||||
| x | a | 1970-01-01T00:00:10 | 17.0 |
|
||||
| y | b | 1970-01-01T00:00:00 | 3.0 |
|
||||
| y | b | 1970-01-01T00:00:05 | 6.0 |
|
||||
| y | b | 1970-01-01T00:00:10 | 8.0 |
|
||||
+------+--------------+---------------------+-------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') -{"otel.m"};
|
||||
|
||||
+--------------+------+------+---------------------+-----------+
|
||||
| service.name | Host | host | ts.time | (- v.val) |
|
||||
+--------------+------+------+---------------------+-----------+
|
||||
| a | h1 | x | 1970-01-01T00:00:00 | -1.0 |
|
||||
| a | h1 | x | 1970-01-01T00:00:05 | -4.0 |
|
||||
| a | h1 | x | 1970-01-01T00:00:10 | -8.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:00 | -2.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:05 | -5.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:10 | -9.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:00 | -3.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:05 | -6.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:10 | -8.0 |
|
||||
+--------------+------+------+---------------------+-----------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') 2 * {"otel.m"};
|
||||
|
||||
+--------------+------+------+---------------------+--------------------+
|
||||
| service.name | Host | host | ts.time | Float64(2) * v.val |
|
||||
+--------------+------+------+---------------------+--------------------+
|
||||
| a | h1 | x | 1970-01-01T00:00:00 | 2.0 |
|
||||
| a | h1 | x | 1970-01-01T00:00:05 | 8.0 |
|
||||
| a | h1 | x | 1970-01-01T00:00:10 | 16.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:00 | 4.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:05 | 10.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:10 | 18.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:00 | 6.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:05 | 12.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:10 | 16.0 |
|
||||
+--------------+------+------+---------------------+--------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} - 1;
|
||||
|
||||
+--------------+------+------+---------------------+--------------------+
|
||||
| service.name | Host | host | ts.time | v.val - Float64(1) |
|
||||
+--------------+------+------+---------------------+--------------------+
|
||||
| a | h1 | x | 1970-01-01T00:00:00 | 0.0 |
|
||||
| a | h1 | x | 1970-01-01T00:00:05 | 3.0 |
|
||||
| a | h1 | x | 1970-01-01T00:00:10 | 7.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:00 | 1.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:05 | 4.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:10 | 8.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:00 | 2.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:05 | 5.0 |
|
||||
| b | h1 | y | 1970-01-01T00:00:10 | 7.0 |
|
||||
+--------------+------+------+---------------------+--------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') timestamp({"otel.m"});
|
||||
|
||||
+---------------------+-------+--------------+------+------+
|
||||
| ts.time | value | service.name | Host | host |
|
||||
+---------------------+-------+--------------+------+------+
|
||||
| 1970-01-01T00:00:00 | 0.0 | a | h1 | x |
|
||||
| 1970-01-01T00:00:00 | 0.0 | a | h2 | x |
|
||||
| 1970-01-01T00:00:00 | 0.0 | b | h1 | y |
|
||||
| 1970-01-01T00:00:05 | 5.0 | a | h1 | x |
|
||||
| 1970-01-01T00:00:05 | 5.0 | a | h2 | x |
|
||||
| 1970-01-01T00:00:05 | 5.0 | b | h1 | y |
|
||||
| 1970-01-01T00:00:10 | 10.0 | a | h1 | x |
|
||||
| 1970-01-01T00:00:10 | 10.0 | a | h2 | x |
|
||||
| 1970-01-01T00:00:10 | 10.0 | b | h1 | y |
|
||||
+---------------------+-------+--------------+------+------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') minute({"otel.m"});
|
||||
|
||||
+---------------------+-----------------------------------+--------------+------+------+
|
||||
| ts.time | date_part(Utf8("minute"),ts.time) | service.name | Host | host |
|
||||
+---------------------+-----------------------------------+--------------+------+------+
|
||||
| 1970-01-01T00:00:00 | 0 | a | h1 | x |
|
||||
| 1970-01-01T00:00:00 | 0 | a | h2 | x |
|
||||
| 1970-01-01T00:00:00 | 0 | b | h1 | y |
|
||||
| 1970-01-01T00:00:05 | 0 | a | h1 | x |
|
||||
| 1970-01-01T00:00:05 | 0 | a | h2 | x |
|
||||
| 1970-01-01T00:00:05 | 0 | b | h1 | y |
|
||||
| 1970-01-01T00:00:10 | 0 | a | h1 | x |
|
||||
| 1970-01-01T00:00:10 | 0 | a | h2 | x |
|
||||
| 1970-01-01T00:00:10 | 0 | b | h1 | y |
|
||||
+---------------------+-----------------------------------+--------------+------+------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (5, 10, '5s') sum by ("service.name") (increase({"otel.m"}[10s]));
|
||||
|
||||
+--------------+---------------------+--------------------------------------------------------------+
|
||||
| service.name | ts.time | sum(prom_increase(ts.time_range,v.val,ts.time,Int64(10000))) |
|
||||
+--------------+---------------------+--------------------------------------------------------------+
|
||||
| a | 1970-01-01T00:00:05 | 9.0 |
|
||||
| a | 1970-01-01T00:00:10 | 16.0 |
|
||||
| b | 1970-01-01T00:00:05 | 6.0 |
|
||||
| b | 1970-01-01T00:00:10 | 4.0 |
|
||||
+--------------+---------------------+--------------------------------------------------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') scalar(sum({"otel.m"})) * {"otel.m", "Host"="h2"};
|
||||
|
||||
+--------------+------+------+---------------------+-------------------------------------------+
|
||||
| service.name | Host | host | ts.time | lhs.scalar(sum(otel.m.v.val)) * rhs.v.val |
|
||||
+--------------+------+------+---------------------+-------------------------------------------+
|
||||
| a | h2 | x | 1970-01-01T00:00:00 | 12.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:05 | 75.0 |
|
||||
| a | h2 | x | 1970-01-01T00:00:10 | 225.0 |
|
||||
+--------------+------+------+---------------------+-------------------------------------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') absent({"otel.m", "service.name"="c"});
|
||||
|
||||
+---------------------+-------+--------------+
|
||||
| ts.time | v.val | service.name |
|
||||
+---------------------+-------+--------------+
|
||||
| 1970-01-01T00:00:00 | 1.0 | c |
|
||||
| 1970-01-01T00:00:05 | 1.0 | c |
|
||||
| 1970-01-01T00:00:10 | 1.0 | c |
|
||||
+---------------------+-------+--------------+
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') histogram_quantile(0.5, {"otel.h"});
|
||||
|
||||
+---------------------+--------------+-------+
|
||||
| ts.time | service.name | v.val |
|
||||
+---------------------+--------------+-------+
|
||||
| 1970-01-01T00:00:00 | a | 0.55 |
|
||||
| 1970-01-01T00:00:05 | a | 0.55 |
|
||||
| 1970-01-01T00:00:10 | a | 0.775 |
|
||||
+---------------------+--------------+-------+
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (0, 10, '5s') {"otel.m"} and {"otel.m", "Host"="h1"};
|
||||
|
||||
+-+-+
|
||||
| plan_type_| plan_|
|
||||
+-+-+
|
||||
| logical_plan_| LeftSemi Join: otel.m.Host = otel.m.Host, otel.m.host = otel.m.host, otel.m.service.name = otel.m.service.name, otel.m.ts.time = otel.m.ts.time_|
|
||||
|_|_Aggregate: groupBy=[[otel.m.ts.time, otel.m.service.name, otel.m.Host, otel.m.host, otel.m.v.val]], aggr=[[]]_|
|
||||
|_|_MergeScan [is_placeholder=false, remote_input=[_|
|
||||
|_| Distinct:_|
|
||||
|_|_PromInstantManipulate: range=[0..10000], lookback=[300000], interval=[5000], time index=[ts.time]_|
|
||||
|_|_PromSeriesDivide: tags=["service.name", "Host", "host"]_|
|
||||
|_|_Sort: otel.m.service.name ASC NULLS FIRST, otel.m.Host ASC NULLS FIRST, otel.m.host ASC NULLS FIRST, otel.m.ts.time ASC NULLS FIRST_|
|
||||
|_|_Filter: otel.m.ts.time >= TimestampMillisecond(-299999, None) AND otel.m.ts.time <= TimestampMillisecond(10000, None)_|
|
||||
|_|_TableScan: otel.m, partial_filters=[otel.m.ts.time >= TimestampMillisecond(-299999, None), otel.m.ts.time <= TimestampMillisecond(10000, None)]_|
|
||||
|_| ]]_|
|
||||
|_|_Projection: otel.m.ts.time, otel.m.service.name, otel.m.Host, otel.m.host_|
|
||||
|_|_PromInstantManipulate: range=[0..10000], lookback=[300000], interval=[5000], time index=[ts.time]_|
|
||||
|_|_PromSeriesDivide: tags=["service.name", "Host", "host"]_|
|
||||
|_|_Sort: otel.m.service.name ASC NULLS FIRST, otel.m.Host ASC NULLS FIRST, otel.m.host ASC NULLS FIRST, otel.m.ts.time ASC NULLS FIRST_|
|
||||
|_|_MergeScan [is_placeholder=false, remote_input=[_|
|
||||
|_| Filter: otel.m.Host = Utf8("h1") AND otel.m.ts.time >= TimestampMillisecond(-299999, None) AND otel.m.ts.time <= TimestampMillisecond(10000, None)_|
|
||||
|_|_TableScan: otel.m, partial_filters=[otel.m.Host = Utf8("h1"), otel.m.ts.time >= TimestampMillisecond(-299999, None), otel.m.ts.time <= TimestampMillisecond(10000, None)] |
|
||||
|_| ]]_|
|
||||
| physical_plan | HashJoinExec: mode=CollectLeft, join_type=RightSemi, on=[(Host@2, Host@2), (host@3, host@3), (service.name@1, service.name@1), (ts.time@0, ts.time@0)], NullsEqual: true_|
|
||||
|_|_CoalescePartitionsExec_|
|
||||
|_|_ProjectionExec: expr=[ts.time@0 as ts.time, service.name@1 as service.name, Host@2 as Host, host@3 as host]_|
|
||||
|_|_PromInstantManipulateExec: range=[0..10000], lookback=[300000], interval=[5000], time index=[ts.time]_|
|
||||
|_|_PromSeriesDivideExec: tags=["service.name", "Host", "host"]_|
|
||||
|_|_SortExec: expr=[service.name@1 ASC, Host@2 ASC, host@3 ASC, ts.time@0 ASC], preserve_REDACTED
|
||||
|_|_RepartitionExec: REDACTED
|
||||
|_|_MergeScanExec: REDACTED
|
||||
|_|_AggregateExec: mode=FinalPartitioned, gby=[ts.time@0 as ts.time, service.name@1 as service.name, Host@2 as Host, host@3 as host, v.val@4 as v.val], aggr=[]_|
|
||||
|_|_RepartitionExec: REDACTED
|
||||
|_|_AggregateExec: mode=Partial, gby=[ts.time@0 as ts.time, service.name@1 as service.name, Host@2 as Host, host@3 as host, v.val@4 as v.val], aggr=[]_|
|
||||
|_|_RepartitionExec: REDACTED
|
||||
|_|_MergeScanExec: REDACTED
|
||||
|_|_|
|
||||
+-+-+
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (0, 10, '5s') topk(1, {"otel.m"});
|
||||
|
||||
+-+-+
|
||||
| plan_type_| plan_|
|
||||
+-+-+
|
||||
| logical_plan_| Projection: otel.m.v.val, otel.m.service.name, otel.m.Host, otel.m.host, otel.m.ts.time_|
|
||||
|_|_Sort: otel.m.ts.time ASC NULLS LAST, row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ASC NULLS LAST_|
|
||||
|_|_Filter: CAST(row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW AS Float64) <= Float64(1)_|
|
||||
|_|_WindowAggr: windowExpr=[[row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW]]_|
|
||||
|_|_MergeScan [is_placeholder=false, remote_input=[_|
|
||||
|_| PromInstantManipulate: range=[0..10000], lookback=[300000], interval=[5000], time index=[ts.time]_|
|
||||
|_|_PromSeriesDivide: tags=["service.name", "Host", "host"]_|
|
||||
|_|_Sort: otel.m.service.name ASC NULLS FIRST, otel.m.Host ASC NULLS FIRST, otel.m.host ASC NULLS FIRST, otel.m.ts.time ASC NULLS FIRST_|
|
||||
|_|_Filter: otel.m.ts.time >= TimestampMillisecond(-299999, None) AND otel.m.ts.time <= TimestampMillisecond(10000, None)_|
|
||||
|_|_TableScan: otel.m, partial_filters=[otel.m.ts.time >= TimestampMillisecond(-299999, None), otel.m.ts.time <= TimestampMillisecond(10000, None)]_|
|
||||
|_| ]]_|
|
||||
| physical_plan | ProjectionExec: expr=[v.val@4 as v.val, service.name@1 as service.name, Host@2 as Host, host@3 as host, ts.time@0 as ts.time]_|
|
||||
|_|_SortPreservingMergeExec: [ts.time@0 ASC NULLS LAST, row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW@5 ASC NULLS LAST]_|
|
||||
|_|_FilterExec: CAST(row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW@5 AS Float64) <= 1_|
|
||||
|_|_BoundedWindowAggExec: wdw=[row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW: Field { "row_number() PARTITION BY [otel.m.ts.time] ORDER BY [otel.m.v.val DESC NULLS FIRST, otel.m.service.name DESC NULLS FIRST, otel.m.Host DESC NULLS FIRST, otel.m.host DESC NULLS FIRST] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW": UInt64 }, frame: ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW], mode=[Sorted] |
|
||||
|_|_SortExec: expr=[ts.time@0 ASC NULLS LAST, v.val@4 DESC, service.name@1 DESC, Host@2 DESC, host@3 DESC], preserve_REDACTED
|
||||
|_|_RepartitionExec: REDACTED
|
||||
|_|_MergeScanExec: REDACTED
|
||||
|_|_|
|
||||
+-+-+
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (5, 10, '5s') sum by ("service.name") (increase({"otel.m"}[10s]));
|
||||
|
||||
+-+-+
|
||||
| plan_type_| plan_|
|
||||
+-+-+
|
||||
| logical_plan_| MergeSort: otel.m.service.name ASC NULLS LAST, otel.m.ts.time ASC NULLS LAST_|
|
||||
|_|_MergeScan [is_placeholder=false, remote_input=[_|
|
||||
|_| Sort: otel.m.service.name ASC NULLS LAST, otel.m.ts.time ASC NULLS LAST_|
|
||||
|_|_Aggregate: groupBy=[[otel.m.service.name, otel.m.ts.time]], aggr=[[sum(prom_increase(ts.time_range,v.val,ts.time,Int64(10000)))]]_|
|
||||
|_|_Filter: prom_increase(ts.time_range,v.val,ts.time,Int64(10000)) IS NOT NULL_|
|
||||
|_|_Projection: otel.m.ts.time, prom_increase(ts.time_range, v.val, otel.m.ts.time, Int64(10000)) AS prom_increase(ts.time_range,v.val,ts.time,Int64(10000)), otel.m.service.name, otel.m.Host, otel.m.host |
|
||||
|_|_PromRangeManipulate: req range=[5000..10000], interval=[5000], eval range=[10000], time index=[ts.time], values=["v.val"]_|
|
||||
|_|_PromSeriesNormalize: offset=[0], time index=[ts.time], filter NaN: [true]_|
|
||||
|_|_PromSeriesDivide: tags=["service.name", "Host", "host"]_|
|
||||
|_|_Sort: otel.m.service.name ASC NULLS FIRST, otel.m.Host ASC NULLS FIRST, otel.m.host ASC NULLS FIRST, otel.m.ts.time ASC NULLS FIRST_|
|
||||
|_|_Filter: otel.m.ts.time >= TimestampMillisecond(-4999, None) AND otel.m.ts.time <= TimestampMillisecond(10000, None)_|
|
||||
|_|_TableScan: otel.m, partial_filters=[otel.m.ts.time >= TimestampMillisecond(-4999, None), otel.m.ts.time <= TimestampMillisecond(10000, None)]_|
|
||||
|_| ]]_|
|
||||
| physical_plan | MergeSortExec: [service.name@0 ASC NULLS LAST, ts.time@1 ASC NULLS LAST]_|
|
||||
|_|_MergeScanExec: REDACTED
|
||||
|_|_|
|
||||
+-+-+
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (0, 10, '5s') histogram_quantile(0.5, {"otel.h"});
|
||||
|
||||
+-+-+
|
||||
| plan_type_| plan_|
|
||||
+-+-+
|
||||
| logical_plan_| HistogramFold: le=le, field=v.val, quantile=0.5_|
|
||||
|_|_MergeScan [is_placeholder=false, remote_input=[_|
|
||||
|_| PromInstantManipulate: range=[0..10000], lookback=[300000], interval=[5000], time index=[ts.time]_|
|
||||
|_|_PromSeriesDivide: tags=["service.name", "le"]_|
|
||||
|_|_Sort: otel.h.service.name ASC NULLS FIRST, otel.h.le ASC NULLS FIRST, otel.h.ts.time ASC NULLS FIRST_|
|
||||
|_|_Filter: otel.h.ts.time >= TimestampMillisecond(-299999, None) AND otel.h.ts.time <= TimestampMillisecond(10000, None)_|
|
||||
|_|_TableScan: otel.h, partial_filters=[otel.h.ts.time >= TimestampMillisecond(-299999, None), otel.h.ts.time <= TimestampMillisecond(10000, None)] |
|
||||
|_| ]]_|
|
||||
| physical_plan | HistogramFoldExec: le=@2, field=@3, quantile=0.5_|
|
||||
|_|_RepartitionExec: REDACTED
|
||||
|_|_SortExec: expr=[service.name@1 ASC NULLS LAST, ts.time@0 ASC NULLS LAST, TRY_CAST(le@2 AS Float64) ASC NULLS LAST], preserve_REDACTED
|
||||
|_|_MergeScanExec: REDACTED
|
||||
|_|_|
|
||||
+-+-+
|
||||
|
||||
DROP TABLE "otel.m";
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
DROP TABLE "otel.h";
|
||||
|
||||
Affected Rows: 0
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
-- https://github.com/GreptimeTeam/greptimedb/issues/9390
|
||||
-- Tag, field and time index names containing dots or upper case letters must
|
||||
-- be resolved as plain column names, not as `relation.column`. `Host` and `host`
|
||||
-- hold different values, so reading one for the other changes the output.
|
||||
CREATE TABLE "otel.m" (
|
||||
"ts.time" TIMESTAMP(3) TIME INDEX,
|
||||
"service.name" STRING,
|
||||
"Host" STRING,
|
||||
host STRING,
|
||||
"v.val" DOUBLE,
|
||||
PRIMARY KEY ("service.name", "Host", host)
|
||||
) PARTITION ON COLUMNS ("service.name") (
|
||||
"service.name" < 'b',
|
||||
"service.name" >= 'b'
|
||||
);
|
||||
|
||||
INSERT INTO "otel.m" VALUES
|
||||
(0, 'a', 'h1', 'x', 1),
|
||||
(0, 'a', 'h2', 'x', 2),
|
||||
(0, 'b', 'h1', 'y', 3),
|
||||
(5000, 'a', 'h1', 'x', 4),
|
||||
(5000, 'a', 'h2', 'x', 5),
|
||||
(5000, 'b', 'h1', 'y', 6),
|
||||
(10000, 'a', 'h1', 'x', 8),
|
||||
(10000, 'a', 'h2', 'x', 9),
|
||||
(10000, 'b', 'h1', 'y', 8);
|
||||
|
||||
CREATE TABLE "otel.h" (
|
||||
"ts.time" TIMESTAMP(3) TIME INDEX,
|
||||
"service.name" STRING,
|
||||
le STRING,
|
||||
"v.val" DOUBLE,
|
||||
PRIMARY KEY ("service.name", le)
|
||||
);
|
||||
|
||||
INSERT INTO "otel.h" VALUES
|
||||
(0, 'a', '0.1', 1),
|
||||
(0, 'a', '1', 3),
|
||||
(0, 'a', '+Inf', 4),
|
||||
(10000, 'a', '0.1', 2),
|
||||
(10000, 'a', '1', 6),
|
||||
(10000, 'a', '+Inf', 10);
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} and {"otel.m", "Host"="h1"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} and on("service.name") {"otel.m", "service.name"="b"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} and on(host) {"otel.m", host="y"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} unless {"otel.m", "Host"="h1"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} unless on("service.name") {"otel.m", "service.name"="b"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} or {"otel.m", "Host"="h1"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') count_values("v.name", {"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') count_values by ("service.name") ("v.name", {"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') topk(1, {"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') bottomk by ("service.name") (1, {"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum by ("service.name") ({"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum by ("Host") ({"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum by (host) ({"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') sum without ("Host") ({"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') -{"otel.m"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') 2 * {"otel.m"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') {"otel.m"} - 1;
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') timestamp({"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') minute({"otel.m"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (5, 10, '5s') sum by ("service.name") (increase({"otel.m"}[10s]));
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') scalar(sum({"otel.m"})) * {"otel.m", "Host"="h2"};
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') absent({"otel.m", "service.name"="c"});
|
||||
|
||||
-- SQLNESS SORT_RESULT 3 1
|
||||
TQL EVAL (0, 10, '5s') histogram_quantile(0.5, {"otel.h"});
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (0, 10, '5s') {"otel.m"} and {"otel.m", "Host"="h1"};
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (0, 10, '5s') topk(1, {"otel.m"});
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (5, 10, '5s') sum by ("service.name") (increase({"otel.m"}[10s]));
|
||||
|
||||
-- SQLNESS REPLACE (peers.*) REDACTED
|
||||
-- SQLNESS REPLACE (partitioning.*) REDACTED
|
||||
-- SQLNESS REPLACE (-+) -
|
||||
-- SQLNESS REPLACE (\s\s+) _
|
||||
TQL EXPLAIN (0, 10, '5s') histogram_quantile(0.5, {"otel.h"});
|
||||
|
||||
DROP TABLE "otel.m";
|
||||
|
||||
DROP TABLE "otel.h";
|
||||
Reference in New Issue
Block a user