diff --git a/Cargo.lock b/Cargo.lock index 519f59c33df..a5e188f70c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6558,6 +6558,7 @@ dependencies = [ "common-catalog", "common-error", "common-macro", + "common-query", "common-recordbatch", "common-telemetry", "datafusion", diff --git a/src/common/query/src/prelude.rs b/src/common/query/src/prelude.rs index e65586e669e..b334edb9030 100644 --- a/src/common/query/src/prelude.rs +++ b/src/common/query/src/prelude.rs @@ -18,3 +18,10 @@ pub use crate::columnar_value::ColumnarValue; pub use crate::function::*; pub use crate::logical_plan::{create_udf, AggregateFunction, Expr, ScalarUdf}; pub use crate::signature::{Signature, TypeSignature, Volatility}; + +/// Default timestamp column name for Prometheus metrics. +pub const GREPTIME_TIMESTAMP: &str = "greptime_timestamp"; +/// Default value column name for Prometheus metrics. +pub const GREPTIME_VALUE: &str = "greptime_value"; +/// Default counter column name for OTLP metrics. +pub const GREPTIME_COUNT: &str = "greptime_count"; diff --git a/src/promql/Cargo.toml b/src/promql/Cargo.toml index 6be12de4e34..fc853365674 100644 --- a/src/promql/Cargo.toml +++ b/src/promql/Cargo.toml @@ -13,6 +13,7 @@ catalog.workspace = true common-catalog.workspace = true common-error.workspace = true common-macro.workspace = true +common-query.workspace = true common-recordbatch.workspace = true common-telemetry.workspace = true datafusion.workspace = true diff --git a/src/promql/src/extension_plan/empty_metric.rs b/src/promql/src/extension_plan/empty_metric.rs index f4c33cf30f6..74d25d8ebb8 100644 --- a/src/promql/src/extension_plan/empty_metric.rs +++ b/src/promql/src/extension_plan/empty_metric.rs @@ -104,8 +104,8 @@ impl EmptyMetric { .map(|expr| { physical_planner.create_physical_expr( expr, - &self.result_schema, - &ArrowSchema::from(self.result_schema.as_ref()), + &self.time_index_schema, + &ArrowSchema::from(self.time_index_schema.as_ref()), session_state, ) }) diff --git a/src/promql/src/planner.rs b/src/promql/src/planner.rs index 7c8176d7b95..3f3a5bd07c8 100644 --- a/src/promql/src/planner.rs +++ b/src/promql/src/planner.rs @@ -19,6 +19,7 @@ use std::time::UNIX_EPOCH; use async_recursion::async_recursion; use catalog::table_source::DfTableSourceProvider; +use common_query::prelude::GREPTIME_VALUE; use datafusion::common::{DFSchemaRef, OwnedTableReference, Result as DfResult}; use datafusion::datasource::DefaultTableSource; use datafusion::logical_expr::expr::{AggregateFunction, Alias, ScalarFunction, ScalarUDF}; @@ -36,8 +37,9 @@ use datatypes::arrow::datatypes::DataType as ArrowDataType; use promql_parser::label::{MatchOp, Matcher, Matchers, METRIC_NAME}; use promql_parser::parser::{ token, AggregateExpr, BinModifier, BinaryExpr as PromBinaryExpr, Call, EvalStmt, - Expr as PromExpr, Function, LabelModifier, MatrixSelector, NumberLiteral, Offset, ParenExpr, - StringLiteral, SubqueryExpr, TokenType, UnaryExpr, VectorMatchCardinality, VectorSelector, + Expr as PromExpr, Function, FunctionArgs as PromFunctionArgs, LabelModifier, MatrixSelector, + NumberLiteral, Offset, ParenExpr, StringLiteral, SubqueryExpr, TokenType, UnaryExpr, + VectorMatchCardinality, VectorSelector, }; use snafu::{ensure, OptionExt, ResultExt}; use table::table::adapter::DfTableProviderAdapter; @@ -63,6 +65,8 @@ use crate::functions::{ const SPECIAL_TIME_FUNCTION: &str = "time"; /// `histogram_quantile` function in PromQL const SPECIAL_HISTOGRAM_QUANTILE: &str = "histogram_quantile"; +/// `vector` function in PromQL +const SPECIAL_VECTOR_FUNCTION: &str = "vector"; /// `le` column for conventional histogram. const LE_COLUMN_NAME: &str = "le"; @@ -289,13 +293,13 @@ impl PromPlanner { let left_field_columns = self.ctx.field_columns.clone(); let left_table_ref: OwnedTableReference = self.ctx.table_name.clone().unwrap_or_default().into(); - let left_tag_cols = self.ctx.tag_columns.clone(); + let left_context = self.ctx.clone(); let right_input = self.prom_expr_to_plan(*rhs.clone()).await?; let right_field_columns = self.ctx.field_columns.clone(); let right_table_ref: OwnedTableReference = self.ctx.table_name.clone().unwrap_or_default().into(); - let right_tag_cols = self.ctx.tag_columns.clone(); + let right_context = self.ctx.clone(); // TODO(ruihang): avoid join if left and right are the same table @@ -304,8 +308,8 @@ impl PromPlanner { return self.set_op_on_non_field_columns( left_input, right_input, - left_tag_cols, - right_tag_cols, + left_context, + right_context, *op, modifier, ); @@ -463,57 +467,14 @@ impl PromPlanner { }) } PromExpr::Call(Call { func, args }) => { - if func.name == SPECIAL_HISTOGRAM_QUANTILE { - if args.args.len() != 2 { - return FunctionInvalidArgumentSnafu { - fn_name: SPECIAL_HISTOGRAM_QUANTILE.to_string(), - } - .fail(); - } - let phi = Self::try_build_float_literal(&args.args[0]).with_context(|| { - FunctionInvalidArgumentSnafu { - fn_name: SPECIAL_HISTOGRAM_QUANTILE.to_string(), - } - })?; - let input = args.args[1].as_ref().clone(); - let input_plan = self.prom_expr_to_plan(input).await?; - - if !self.ctx.has_le_tag() { - return ColumnNotFoundSnafu { - col: LE_COLUMN_NAME.to_string(), - } - .fail(); - } - let time_index_column = - self.ctx.time_index_column.clone().with_context(|| { - TimeIndexNotFoundSnafu { - table: self.ctx.table_name.clone().unwrap_or_default(), - } - })?; - // FIXME(ruihang): support multi fields - let field_column = self - .ctx - .field_columns - .first() - .with_context(|| FunctionInvalidArgumentSnafu { - fn_name: SPECIAL_HISTOGRAM_QUANTILE.to_string(), - })? - .clone(); - - return Ok(LogicalPlan::Extension(Extension { - node: Arc::new( - HistogramFold::new( - LE_COLUMN_NAME.to_string(), - field_column, - time_index_column, - phi, - input_plan, - ) - .context(DataFusionPlanningSnafu)?, - ), - })); + // some special functions that are not expression but a plan + match func.name { + SPECIAL_HISTOGRAM_QUANTILE => return self.create_histogram_plan(args).await, + SPECIAL_VECTOR_FUNCTION => return self.create_vector_plan(args).await, + _ => {} } + // transform function arguments let args = self.create_function_args(&args.args)?; let input = if let Some(prom_expr) = args.input { self.prom_expr_to_plan(prom_expr).await? @@ -1303,6 +1264,93 @@ impl PromPlanner { Ok(exprs) } + /// Create a [SPECIAL_HISTOGRAM_QUANTILE] plan. + async fn create_histogram_plan(&mut self, args: &PromFunctionArgs) -> Result { + if args.args.len() != 2 { + return FunctionInvalidArgumentSnafu { + fn_name: SPECIAL_HISTOGRAM_QUANTILE.to_string(), + } + .fail(); + } + let phi = Self::try_build_float_literal(&args.args[0]).with_context(|| { + FunctionInvalidArgumentSnafu { + fn_name: SPECIAL_HISTOGRAM_QUANTILE.to_string(), + } + })?; + let input = args.args[1].as_ref().clone(); + let input_plan = self.prom_expr_to_plan(input).await?; + + if !self.ctx.has_le_tag() { + return ColumnNotFoundSnafu { + col: LE_COLUMN_NAME.to_string(), + } + .fail(); + } + let time_index_column = + self.ctx + .time_index_column + .clone() + .with_context(|| TimeIndexNotFoundSnafu { + table: self.ctx.table_name.clone().unwrap_or_default(), + })?; + // FIXME(ruihang): support multi fields + let field_column = self + .ctx + .field_columns + .first() + .with_context(|| FunctionInvalidArgumentSnafu { + fn_name: SPECIAL_HISTOGRAM_QUANTILE.to_string(), + })? + .clone(); + + Ok(LogicalPlan::Extension(Extension { + node: Arc::new( + HistogramFold::new( + LE_COLUMN_NAME.to_string(), + field_column, + time_index_column, + phi, + input_plan, + ) + .context(DataFusionPlanningSnafu)?, + ), + })) + } + + /// Create a [SPECIAL_VECTOR_FUNCTION] plan + async fn create_vector_plan(&mut self, args: &PromFunctionArgs) -> Result { + if args.args.len() != 1 { + return FunctionInvalidArgumentSnafu { + fn_name: SPECIAL_VECTOR_FUNCTION.to_string(), + } + .fail(); + } + let lit = Self::try_build_float_literal(&args.args[0]).with_context(|| { + FunctionInvalidArgumentSnafu { + fn_name: SPECIAL_VECTOR_FUNCTION.to_string(), + } + })?; + + // reuse `SPECIAL_TIME_FUNCTION` as name of time index column + self.ctx.time_index_column = Some(SPECIAL_TIME_FUNCTION.to_string()); + self.ctx.table_name = Some(String::new()); + self.ctx.tag_columns = vec![]; + self.ctx.field_columns = vec![GREPTIME_VALUE.to_string()]; + Ok(LogicalPlan::Extension(Extension { + node: Arc::new( + EmptyMetric::new( + self.ctx.start, + self.ctx.end, + self.ctx.interval, + SPECIAL_TIME_FUNCTION.to_string(), + GREPTIME_VALUE.to_string(), + Some(DfExpr::Literal(ScalarValue::Float64(Some(lit)))), + ) + .context(DataFusionPlanningSnafu)?, + ), + })) + } + /// Try to build a DataFusion Literal Expression from PromQL Expr, return /// `None` if the input is not a literal expression. fn try_build_literal_expr(expr: &PromExpr) -> Option { @@ -1491,19 +1539,35 @@ impl PromPlanner { /// Build a set operator (AND/OR/UNLESS) fn set_op_on_non_field_columns( - &self, + &mut self, left: LogicalPlan, right: LogicalPlan, - left_tag_cols: Vec, - right_tag_cols: Vec, + left_context: PromPlannerContext, + right_context: PromPlannerContext, op: TokenType, modifier: &Option, ) -> Result { - let mut left_tag_col_set = left_tag_cols.into_iter().collect::>(); - let mut right_tag_col_set = right_tag_cols.into_iter().collect::>(); + let mut left_tag_col_set = left_context + .tag_columns + .iter() + .cloned() + .collect::>(); + let mut right_tag_col_set = right_context + .tag_columns + .iter() + .cloned() + .collect::>(); if matches!(op.id(), token::T_LOR) { - return self.or_operator(left, right, left_tag_col_set, right_tag_col_set, modifier); + return self.or_operator( + left, + right, + left_tag_col_set, + right_tag_col_set, + left_context, + right_context, + modifier, + ); } // apply modifier @@ -1585,19 +1649,24 @@ impl PromPlanner { .build() .context(DataFusionPlanningSnafu), token::T_LOR => { - self.or_operator(left, right, left_tag_col_set, right_tag_col_set, modifier) + // OR is handled at the beginning of this function, as it cannot + // be expressed using JOIN like AND and UNLESS. + unreachable!() } _ => UnexpectedTokenSnafu { token: op }.fail(), } } // TODO(ruihang): change function name + #[allow(clippy::too_many_arguments)] fn or_operator( - &self, + &mut self, left: LogicalPlan, right: LogicalPlan, left_tag_cols_set: HashSet, right_tag_cols_set: HashSet, + left_context: PromPlannerContext, + right_context: PromPlannerContext, modifier: &Option, ) -> Result { // prepare hash sets @@ -1623,18 +1692,37 @@ impl PromPlanner { .as_ref() .map(|r| r.to_string()) .unwrap_or_default(); + let left_time_index_column = + left_context + .time_index_column + .clone() + .with_context(|| TimeIndexNotFoundSnafu { + table: left_qualifier_string.clone(), + })?; + let right_time_index_column = + right_context + .time_index_column + .clone() + .with_context(|| TimeIndexNotFoundSnafu { + table: right_qualifier_string.clone(), + })?; // step 0: fill all columns in output schema - let all_columns_set = left + let mut all_columns_set = left .schema() .fields() .iter() .chain(right.schema().fields().iter()) .map(|field| field.name().clone()) .collect::>(); + // remove time index column + all_columns_set.remove(&left_time_index_column); + all_columns_set.remove(&right_time_index_column); let mut all_columns = all_columns_set.into_iter().collect::>(); // sort to ensure the generated schema is not volatile all_columns.sort_unstable(); + // use left time index column name as the result time index column name + all_columns.insert(0, left_time_index_column.clone()); // step 1: align schema using project, fill non-exist columns with null let left_proj_exprs = all_columns.iter().map(|col| { @@ -1644,13 +1732,21 @@ impl PromPlanner { DfExpr::Column(Column::new(left_qualifier.clone(), col)) } }); - let right_proj_exprs = all_columns.iter().map(|col| { + let right_time_index_expr = DfExpr::Column(Column::new( + right_qualifier.clone(), + right_time_index_column, + )) + .alias(left_time_index_column.clone()); + let right_proj_exprs_without_time_index = all_columns.iter().skip(1).map(|col| { if tags_not_in_right.contains(col) { DfExpr::Literal(ScalarValue::Utf8(None)).alias(col.to_string()) } else { DfExpr::Column(Column::new(right_qualifier.clone(), col)) } }); + let right_proj_exprs = [right_time_index_expr] + .into_iter() + .chain(right_proj_exprs_without_time_index); let left_projected = LogicalPlanBuilder::from(left) .project(left_proj_exprs) @@ -1691,13 +1787,17 @@ impl PromPlanner { left_projected, right_projected, match_columns, - self.ctx.time_index_column.clone().unwrap(), + left_time_index_column.clone(), schema, ); let result = LogicalPlan::Extension(Extension { node: Arc::new(union_distinct_on), }); + // step 4: update context + self.ctx.time_index_column = Some(left_time_index_column); + self.ctx.tag_columns = all_tags.into_iter().collect(); + Ok(result) } diff --git a/src/query/src/sql.rs b/src/query/src/sql.rs index 869cb883ef9..28e803f48e7 100644 --- a/src/query/src/sql.rs +++ b/src/query/src/sql.rs @@ -25,6 +25,7 @@ use common_datasource::file_format::{infer_schemas, FileFormat, Format}; use common_datasource::lister::{Lister, Source}; use common_datasource::object_store::build_backend; use common_datasource::util::find_dir_and_filename; +use common_query::prelude::GREPTIME_TIMESTAMP; use common_query::Output; use common_recordbatch::{RecordBatch, RecordBatches}; use common_time::Timestamp; @@ -57,8 +58,6 @@ const NULLABLE_YES: &str = "YES"; const NULLABLE_NO: &str = "NO"; const PRI_KEY: &str = "PRI"; -const GREPTIME_TIMESTAMP: &str = "greptime_timestamp"; - static DESCRIBE_TABLE_OUTPUT_SCHEMA: Lazy> = Lazy::new(|| { Arc::new(Schema::new(vec![ ColumnSchema::new( diff --git a/src/servers/src/http/prometheus.rs b/src/servers/src/http/prometheus.rs index 2aae0b3a000..ee8939744ff 100644 --- a/src/servers/src/http/prometheus.rs +++ b/src/servers/src/http/prometheus.rs @@ -22,6 +22,7 @@ use common_catalog::consts::DEFAULT_SCHEMA_NAME; use common_catalog::parse_catalog_and_schema_from_db_string; use common_error::ext::ErrorExt; use common_error::status_code::StatusCode; +use common_query::prelude::{GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use common_query::Output; use common_recordbatch::RecordBatches; use common_time::util::{current_time_rfc3339, yesterday_rfc3339}; @@ -43,7 +44,7 @@ use snafu::{Location, OptionExt, ResultExt}; use crate::error::{ CollectRecordbatchSnafu, Error, InternalSnafu, InvalidQuerySnafu, Result, UnexpectedResultSnafu, }; -use crate::prom_store::{FIELD_COLUMN_NAME, METRIC_NAME_LABEL, TIMESTAMP_COLUMN_NAME}; +use crate::prom_store::METRIC_NAME_LABEL; use crate::prometheus_handler::PrometheusHandlerRef; #[derive(Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)] @@ -499,8 +500,8 @@ pub async fn labels_query( } } - let _ = labels.remove(TIMESTAMP_COLUMN_NAME); - let _ = labels.remove(FIELD_COLUMN_NAME); + let _ = labels.remove(GREPTIME_TIMESTAMP); + let _ = labels.remove(GREPTIME_VALUE); let mut sorted_labels: Vec = labels.into_iter().collect(); sorted_labels.sort(); diff --git a/src/servers/src/opentsdb.rs b/src/servers/src/opentsdb.rs index 07cde1e1476..8f0ee6300fa 100644 --- a/src/servers/src/opentsdb.rs +++ b/src/servers/src/opentsdb.rs @@ -22,6 +22,7 @@ use std::sync::Arc; use api::v1::RowInsertRequests; use async_trait::async_trait; +use common_query::prelude::{GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use common_runtime::Runtime; use common_telemetry::logging::error; use futures::StreamExt; @@ -31,7 +32,6 @@ use self::codec::DataPoint; use crate::error::Result; use crate::opentsdb::connection::Connection; use crate::opentsdb::handler::Handler; -use crate::prom_store::{FIELD_COLUMN_NAME, TIMESTAMP_COLUMN_NAME}; use crate::query_handler::OpentsdbProtocolHandlerRef; use crate::row_writer::{self, MultiTableData}; use crate::server::{AbortableStream, BaseTcpServer, Server}; @@ -151,11 +151,11 @@ pub fn data_point_to_grpc_row_insert_requests( row_writer::write_tags(table_data, tags.into_iter(), &mut one_row)?; // value - row_writer::write_f64(table_data, FIELD_COLUMN_NAME, value, &mut one_row)?; + row_writer::write_f64(table_data, GREPTIME_VALUE, value, &mut one_row)?; // timestamp row_writer::write_ts_millis( table_data, - TIMESTAMP_COLUMN_NAME, + GREPTIME_TIMESTAMP, Some(timestamp), &mut one_row, )?; diff --git a/src/servers/src/opentsdb/codec.rs b/src/servers/src/opentsdb/codec.rs index 55e16046055..ae7b8354cec 100644 --- a/src/servers/src/opentsdb/codec.rs +++ b/src/servers/src/opentsdb/codec.rs @@ -13,12 +13,10 @@ // limitations under the License. use api::v1::{column, Column, ColumnDataType, InsertRequest as GrpcInsertRequest, SemanticType}; +use common_query::prelude::{GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use crate::error::{self, Result}; -pub const OPENTSDB_TIMESTAMP_COLUMN_NAME: &str = "greptime_timestamp"; -pub const OPENTSDB_FIELD_COLUMN_NAME: &str = "greptime_value"; - #[derive(Debug, Clone)] pub struct DataPoint { metric: String, @@ -131,7 +129,7 @@ impl DataPoint { let mut columns = Vec::with_capacity(2 + self.tags.len()); let ts_column = Column { - column_name: OPENTSDB_TIMESTAMP_COLUMN_NAME.to_string(), + column_name: GREPTIME_TIMESTAMP.to_string(), values: Some(column::Values { timestamp_millisecond_values: vec![self.ts_millis], ..Default::default() @@ -143,7 +141,7 @@ impl DataPoint { columns.push(ts_column); let field_column = Column { - column_name: OPENTSDB_FIELD_COLUMN_NAME.to_string(), + column_name: GREPTIME_VALUE.to_string(), values: Some(column::Values { f64_values: vec![self.value], ..Default::default() @@ -269,7 +267,7 @@ mod test { assert_eq!(row_count, 1); assert_eq!(columns.len(), 4); - assert_eq!(columns[0].column_name, OPENTSDB_TIMESTAMP_COLUMN_NAME); + assert_eq!(columns[0].column_name, GREPTIME_TIMESTAMP); assert_eq!( columns[0] .values @@ -279,7 +277,7 @@ mod test { vec![1000] ); - assert_eq!(columns[1].column_name, OPENTSDB_FIELD_COLUMN_NAME); + assert_eq!(columns[1].column_name, GREPTIME_VALUE); assert_eq!(columns[1].values.as_ref().unwrap().f64_values, vec![1.0]); assert_eq!(columns[2].column_name, "tagk1"); diff --git a/src/servers/src/otlp.rs b/src/servers/src/otlp.rs index 0f35a7b39ef..5b92d12cb62 100644 --- a/src/servers/src/otlp.rs +++ b/src/servers/src/otlp.rs @@ -15,7 +15,3 @@ pub mod metrics; pub mod plugin; pub mod trace; - -const GREPTIME_TIMESTAMP: &str = "greptime_timestamp"; -const GREPTIME_VALUE: &str = "greptime_value"; -const GREPTIME_COUNT: &str = "greptime_count"; diff --git a/src/servers/src/otlp/metrics.rs b/src/servers/src/otlp/metrics.rs index cd7bbc7db81..fd8dcfc3292 100644 --- a/src/servers/src/otlp/metrics.rs +++ b/src/servers/src/otlp/metrics.rs @@ -14,11 +14,11 @@ use api::v1::{RowInsertRequests, Value}; use common_grpc::writer::Precision; +use common_query::prelude::{GREPTIME_COUNT, GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use opentelemetry_proto::tonic::collector::metrics::v1::ExportMetricsServiceRequest; use opentelemetry_proto::tonic::common::v1::{any_value, KeyValue}; use opentelemetry_proto::tonic::metrics::v1::{metric, number_data_point, *}; -use super::{GREPTIME_COUNT, GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use crate::error::Result; use crate::row_writer::{self, MultiTableData, TableData}; diff --git a/src/servers/src/otlp/trace.rs b/src/servers/src/otlp/trace.rs index 16de53f5656..88a5d9b3507 100644 --- a/src/servers/src/otlp/trace.rs +++ b/src/servers/src/otlp/trace.rs @@ -15,10 +15,10 @@ use api::v1::value::ValueData; use api::v1::{ColumnDataType, RowInsertRequests}; use common_grpc::writer::Precision; +use common_query::prelude::{GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use opentelemetry_proto::tonic::collector::trace::v1::ExportTraceServiceRequest; use self::span::{parse_span, TraceSpan, TraceSpans}; -use super::{GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use crate::error::Result; use crate::row_writer::{self, MultiTableData, TableData}; diff --git a/src/servers/src/prom_store.rs b/src/servers/src/prom_store.rs index 15183e217a4..52591678b67 100644 --- a/src/servers/src/prom_store.rs +++ b/src/servers/src/prom_store.rs @@ -21,6 +21,7 @@ use std::hash::{Hash, Hasher}; use api::prom_store::remote::label_matcher::Type as MatcherType; use api::prom_store::remote::{Label, Query, Sample, TimeSeries, WriteRequest}; use api::v1::RowInsertRequests; +use common_query::prelude::{GREPTIME_TIMESTAMP, GREPTIME_VALUE}; use common_recordbatch::{RecordBatch, RecordBatches}; use common_time::timestamp::TimeUnit; use datafusion::prelude::{col, lit, regexp_match, Expr}; @@ -35,8 +36,6 @@ use snap::raw::{Decoder, Encoder}; use crate::error::{self, Result}; use crate::row_writer::{self, MultiTableData}; -pub const TIMESTAMP_COLUMN_NAME: &str = "greptime_timestamp"; -pub const FIELD_COLUMN_NAME: &str = "greptime_value"; pub const METRIC_NAME_LABEL: &str = "__name__"; /// Metrics for push gateway protocol @@ -73,9 +72,8 @@ pub fn query_to_plan(dataframe: DataFrame, q: &Query) -> Result { 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))); + conditions.push(col(GREPTIME_TIMESTAMP).gt_eq(lit_timestamp_millisecond(start_timestamp_ms))); + conditions.push(col(GREPTIME_TIMESTAMP).lt_eq(lit_timestamp_millisecond(end_timestamp_ms))); for m in label_matches { let name = &m.name; @@ -204,9 +202,7 @@ fn collect_timeseries_ids(table_name: &str, recordbatch: &RecordBatch) -> Vec Result> { - let ts_column = recordbatch.column_by_name(TIMESTAMP_COLUMN_NAME).context( + let ts_column = recordbatch.column_by_name(GREPTIME_TIMESTAMP).context( error::InvalidPromRemoteReadQueryResultSnafu { msg: "missing greptime_timestamp column in query result", }, @@ -254,7 +250,7 @@ fn recordbatch_to_timeseries(table: &str, recordbatch: RecordBatch) -> Result Result<(RowInsertRe }); row_writer::write_tags(table_data, kvs, &mut one_row)?; // value - row_writer::write_f64(table_data, FIELD_COLUMN_NAME, *value, &mut one_row)?; + row_writer::write_f64(table_data, GREPTIME_VALUE, *value, &mut one_row)?; // timestamp row_writer::write_ts_millis( table_data, - TIMESTAMP_COLUMN_NAME, + GREPTIME_TIMESTAMP, Some(*timestamp), &mut one_row, )?; @@ -494,15 +490,11 @@ mod tests { let schema = Arc::new(Schema::new(vec![ ColumnSchema::new( - TIMESTAMP_COLUMN_NAME, + GREPTIME_TIMESTAMP, ConcreteDataType::timestamp_millisecond_datatype(), true, ), - ColumnSchema::new( - FIELD_COLUMN_NAME, - ConcreteDataType::float64_datatype(), - true, - ), + ColumnSchema::new(GREPTIME_VALUE, ConcreteDataType::float64_datatype(), true), ColumnSchema::new("instance", ConcreteDataType::string_datatype(), true), ColumnSchema::new("job", ConcreteDataType::string_datatype(), true), ])); @@ -701,15 +693,11 @@ mod tests { fn test_recordbatches_to_timeseries() { let schema = Arc::new(Schema::new(vec![ ColumnSchema::new( - TIMESTAMP_COLUMN_NAME, + GREPTIME_TIMESTAMP, ConcreteDataType::timestamp_millisecond_datatype(), true, ), - ColumnSchema::new( - FIELD_COLUMN_NAME, - ConcreteDataType::float64_datatype(), - true, - ), + ColumnSchema::new(GREPTIME_VALUE, ConcreteDataType::float64_datatype(), true), ColumnSchema::new("instance", ConcreteDataType::string_datatype(), true), ])); diff --git a/tests/cases/standalone/common/promql/set_operation.result b/tests/cases/standalone/common/promql/set_operation.result index 15a7a865a31..31a0a6638fd 100644 --- a/tests/cases/standalone/common/promql/set_operation.result +++ b/tests/cases/standalone/common/promql/set_operation.result @@ -6,7 +6,7 @@ create table http_requests ( job string, instance string, g string, -- for `group` - val double, + greptime_value double, primary key (job, instance, g) ); @@ -32,7 +32,7 @@ Affected Rows: 0 create table vector_matching_a( ts timestamp time index, l string primary key, - val double, + greptime_value double, ); Affected Rows: 0 @@ -49,12 +49,12 @@ Affected Rows: 2 -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} and http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 0 | canary | 300.0 | -| 1970-01-01T00:50:00 | app | 0 | canary | 700.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 0 | canary | 300.0 | +| 1970-01-01T00:50:00 | app | 0 | canary | 700.0 | ++---------------------+-----+----------+--------+----------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and http_requests{instance="0"} -- {group="canary", instance="0", job="api-server"} 301 @@ -62,12 +62,12 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} and http_requests{instance -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and http_requests{instance="0"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and on(instance, job) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -75,12 +75,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and http_requests{in -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance, job) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and on(instance) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -88,12 +88,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance, job -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and ignoring(group) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -101,12 +101,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and on(instance) htt -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m (http_requests{group="canary"} + 1) and ignoring(group, job) http_requests{instance="0", group="production"} -- {group="canary", instance="0", job="api-server"} 301 @@ -114,12 +114,12 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g) http -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g, job) http_requests{instance="0", g="production"}; -+-----+----------+--------+---------------------+------------------+ -| job | instance | g | ts | val + Float64(1) | -+-----+----------+--------+---------------------+------------------+ -| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | -| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | -+-----+----------+--------+---------------------+------------------+ ++-----+----------+--------+---------------------+-----------------------------+ +| job | instance | g | ts | greptime_value + Float64(1) | ++-----+----------+--------+---------------------+-----------------------------+ +| api | 0 | canary | 1970-01-01T00:50:00 | 301.0 | +| app | 0 | canary | 1970-01-01T00:50:00 | 701.0 | ++-----+----------+--------+---------------------+-----------------------------+ -- eval instant at 50m http_requests{group="canary"} or http_requests{group="production"} -- http_requests{group="canary", instance="0", job="api-server"} 300 @@ -133,18 +133,18 @@ tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) and ignoring(g, job) -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} or http_requests{g="production"}; -+------------+----------+-----+---------------------+-------+ -| g | instance | job | ts | val | -+------------+----------+-----+---------------------+-------+ -| canary | 0 | api | 1970-01-01T00:50:00 | 300.0 | -| canary | 0 | app | 1970-01-01T00:50:00 | 700.0 | -| canary | 1 | api | 1970-01-01T00:50:00 | 400.0 | -| canary | 1 | app | 1970-01-01T00:50:00 | 800.0 | -| production | 0 | api | 1970-01-01T00:50:00 | 100.0 | -| production | 0 | app | 1970-01-01T00:50:00 | 500.0 | -| production | 1 | api | 1970-01-01T00:50:00 | 200.0 | -| production | 1 | app | 1970-01-01T00:50:00 | 600.0 | -+------------+----------+-----+---------------------+-------+ ++---------------------+------------+----------------+----------+-----+ +| ts | g | greptime_value | instance | job | ++---------------------+------------+----------------+----------+-----+ +| 1970-01-01T00:50:00 | canary | 300.0 | 0 | api | +| 1970-01-01T00:50:00 | canary | 400.0 | 1 | api | +| 1970-01-01T00:50:00 | canary | 700.0 | 0 | app | +| 1970-01-01T00:50:00 | canary | 800.0 | 1 | app | +| 1970-01-01T00:50:00 | production | 100.0 | 0 | api | +| 1970-01-01T00:50:00 | production | 200.0 | 1 | api | +| 1970-01-01T00:50:00 | production | 500.0 | 0 | app | +| 1970-01-01T00:50:00 | production | 600.0 | 1 | app | ++---------------------+------------+----------------+----------+-----+ -- # On overlap the rhs samples must be dropped. -- eval instant at 50m (http_requests{group="canary"} + 1) or http_requests{instance="1"} @@ -157,7 +157,7 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} or http_requests{g="produc -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) or http_requests{instance="1"}; -Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named http_requests.val. Valid fields are http_requests.job, http_requests.instance, http_requests.g, http_requests.ts, "val + Float64(1)". +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named http_requests.greptime_value. Valid fields are http_requests.job, http_requests.instance, http_requests.g, http_requests.ts, "greptime_value + Float64(1)". -- # Matching only on instance excludes everything that has instance=0/1 but includes -- # entries without the instance label. @@ -172,7 +172,7 @@ Error: 1004(InvalidArguments), Internal error during building DataFusion plan: N -- NOT SUPPORTED: `or` tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) or on(instance) (http_requests or cpu_count or vector_matching_a); -Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.val. Valid fields are cpu_count.ts. +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.greptime_value. Valid fields are cpu_count.ts. -- eval instant at 50m (http_requests{group="canary"} + 1) or ignoring(l, group, job) (http_requests or cpu_count or vector_matching_a) -- {group="canary", instance="0", job="api-server"} 301 @@ -185,7 +185,7 @@ Error: 1004(InvalidArguments), Internal error during building DataFusion plan: N -- NOT SUPPORTED: `or` tql eval (3000, 3000, '1s') (http_requests{g="canary"} + 1) or ignoring(l, g, job) (http_requests or cpu_count or vector_matching_a); -Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.val. Valid fields are cpu_count.ts. +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named cpu_count.greptime_value. Valid fields are cpu_count.ts. -- eval instant at 50m http_requests{group="canary"} unless http_requests{instance="0"} -- http_requests{group="canary", instance="1", job="api-server"} 400 @@ -193,12 +193,12 @@ Error: 1004(InvalidArguments), Internal error during building DataFusion plan: N -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} unless http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | -| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | +| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | ++---------------------+-----+----------+--------+----------------+ -- eval instant at 50m http_requests{group="canary"} unless on(job) http_requests{instance="0"} tql eval (3000, 3000, '1s') http_requests{g="canary"} unless on(job) http_requests{instance="0"}; @@ -212,12 +212,12 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} unless on(job) http_reques -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} unless on(job, instance) http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | -| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | +| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | ++---------------------+-----+----------+--------+----------------+ -- eval instant at 50m http_requests{group="canary"} unless ignoring(group, instance) http_requests{instance="0"} tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g, instance) http_requests{instance="0"}; @@ -231,12 +231,12 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g, instanc -- SQLNESS SORT_RESULT 3 1 tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g) http_requests{instance="0"}; -+---------------------+-----+----------+--------+-------+ -| ts | job | instance | g | val | -+---------------------+-----+----------+--------+-------+ -| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | -| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | -+---------------------+-----+----------+--------+-------+ ++---------------------+-----+----------+--------+----------------+ +| ts | job | instance | g | greptime_value | ++---------------------+-----+----------+--------+----------------+ +| 1970-01-01T00:50:00 | api | 1 | canary | 400.0 | +| 1970-01-01T00:50:00 | app | 1 | canary | 800.0 | ++---------------------+-----+----------+--------+----------------+ -- # https://github.com/prometheus/prometheus/issues/1489 -- eval instant at 50m http_requests AND ON (dummy) vector(1) @@ -251,7 +251,7 @@ tql eval (3000, 3000, '1s') http_requests{g="canary"} unless ignoring(g) http_re -- NOT SUPPORTED: `vector()` tql eval (3000, 3000, '1s') http_requests AND ON (dummy) vector(1); -Error: 1004(InvalidArguments), Unsupported expr type: vector +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named time. Valid fields are http_requests.ts, http_requests.job, http_requests.instance, http_requests.g, http_requests.greptime_value. -- eval instant at 50m http_requests AND IGNORING (group, instance, job) vector(1) -- http_requests{group="canary", instance="0", job="api-server"} 300 @@ -265,7 +265,7 @@ Error: 1004(InvalidArguments), Unsupported expr type: vector -- NOT SUPPORTED: `vector()` tql eval (3000, 3000, '1s') http_requests AND IGNORING (g, instance, job) vector(1); -Error: 1004(InvalidArguments), Unsupported expr type: vector +Error: 1004(InvalidArguments), Internal error during building DataFusion plan: No field named time. Valid fields are http_requests.ts, http_requests.job, http_requests.instance, http_requests.g, http_requests.greptime_value. drop table http_requests; @@ -280,7 +280,7 @@ drop table vector_matching_a; Affected Rows: 0 -- the following cases are not from Prometheus. -create table t1 (ts timestamp time index, job string primary key, val double); +create table t1 (ts timestamp time index, job string primary key, greptime_value double); Affected Rows: 0 @@ -288,7 +288,7 @@ insert into t1 values (0, "a", 1.0), (500000, "b", 2.0), (1000000, "a", 3.0), (1 Affected Rows: 4 -create table t2 (ts timestamp time index, val double); +create table t2 (ts timestamp time index, greptime_value double); Affected Rows: 0 @@ -299,102 +299,102 @@ Affected Rows: 7 -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t1 or t2; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t1 or on () t2; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t1 or on (job) t2; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t2 or t1; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t2 or on () t1; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ -- SQLNESS SORT_RESULT 3 1 tql eval (0, 2000, '400') t2 or on(job) t1; -+-----+---------------------+-----+ -| job | ts | val | -+-----+---------------------+-----+ -| | 1970-01-01T00:00:00 | 0.0 | -| | 1970-01-01T00:06:40 | 0.0 | -| | 1970-01-01T00:13:20 | 0.0 | -| | 1970-01-01T00:20:00 | 0.0 | -| | 1970-01-01T00:26:40 | 0.0 | -| | 1970-01-01T00:33:20 | 0.0 | -| a | 1970-01-01T00:00:00 | 1.0 | -| a | 1970-01-01T00:20:00 | 3.0 | -| b | 1970-01-01T00:13:20 | 2.0 | -| c | 1970-01-01T00:26:40 | 4.0 | -+-----+---------------------+-----+ ++---------------------+----------------+-----+ +| ts | greptime_value | job | ++---------------------+----------------+-----+ +| 1970-01-01T00:00:00 | 0.0 | | +| 1970-01-01T00:00:00 | 1.0 | a | +| 1970-01-01T00:06:40 | 0.0 | | +| 1970-01-01T00:13:20 | 0.0 | | +| 1970-01-01T00:13:20 | 2.0 | b | +| 1970-01-01T00:20:00 | 0.0 | | +| 1970-01-01T00:20:00 | 3.0 | a | +| 1970-01-01T00:26:40 | 0.0 | | +| 1970-01-01T00:26:40 | 4.0 | c | +| 1970-01-01T00:33:20 | 0.0 | | ++---------------------+----------------+-----+ drop table t1; diff --git a/tests/cases/standalone/common/promql/set_operation.sql b/tests/cases/standalone/common/promql/set_operation.sql index 6a71711bd89..521791a02c4 100644 --- a/tests/cases/standalone/common/promql/set_operation.sql +++ b/tests/cases/standalone/common/promql/set_operation.sql @@ -7,7 +7,7 @@ create table http_requests ( job string, instance string, g string, -- for `group` - val double, + greptime_value double, primary key (job, instance, g) ); @@ -27,7 +27,7 @@ create table cpu_count(ts timestamp time index); create table vector_matching_a( ts timestamp time index, l string primary key, - val double, + greptime_value double, ); insert into vector_matching_a values @@ -176,11 +176,11 @@ drop table vector_matching_a; -- the following cases are not from Prometheus. -create table t1 (ts timestamp time index, job string primary key, val double); +create table t1 (ts timestamp time index, job string primary key, greptime_value double); insert into t1 values (0, "a", 1.0), (500000, "b", 2.0), (1000000, "a", 3.0), (1500000, "c", 4.0); -create table t2 (ts timestamp time index, val double); +create table t2 (ts timestamp time index, greptime_value double); insert into t2 values (0, 0), (300000, 0), (600000, 0), (900000, 0), (1200000, 0), (1500000, 0), (1800000, 0);