feat(influxql): minimal SHOW RETENTION POLICIES implementation (#8433)

For backwards compatibility with version 1 clients support a minimal
implementation of SHOW RETENTION POLICIES. This advertises a single,
default, retention policy for any database. This is suffiecient for
compatibility with the grafana plugin and avoids the need for
cross-database catalog queries in the querier.

The values used for the "duration", "shardGroupDuration", and
"resourceN" are the same canned values used in the cloud 2
implementation.

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
pull/24376/head
Martin Hilton 2023-08-07 14:39:53 +01:00 committed by GitHub
parent db1429b37d
commit 8e2662befb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 5 deletions

View File

@ -98,3 +98,12 @@ SHOW TAG KEYS WHERE tag0 = 'a';
SHOW TAG KEYS ON my_db;
SHOW TAG KEYS FROM x.my_db;
SHOW TAG KEYS FROM x.y.my_db;
-- SHOW RETENTION POLICIES
-- N.B. The current implemention is extremely simplistic and assumes
-- every database contains a single, default, retention policy. This
-- to avoid the need for complex catalogue queries.
SHOW RETENTION POLICIES;
-- unimplemented features in `SHOW RETENTION POLICIES`
SHOW RETENTION POLICIES ON my_db;

View File

@ -1460,4 +1460,13 @@ Error while planning query: This feature is not implemented: SHOW TAG KEYS ON <d
-- InfluxQL: SHOW TAG KEYS FROM x.my_db;
Error while planning query: This feature is not implemented: retention policy in from clause
-- InfluxQL: SHOW TAG KEYS FROM x.y.my_db;
Error while planning query: This feature is not implemented: database name in from clause
Error while planning query: This feature is not implemented: database name in from clause
-- InfluxQL: SHOW RETENTION POLICIES;
name: retention_policies
+---------+----------+--------------------+----------+---------+
| name | duration | shardGroupDuration | replicaN | default |
+---------+----------+--------------------+----------+---------+
| autogen | 0s | 168h0m0s | 1 | true |
+---------+----------+--------------------+----------+---------+
-- InfluxQL: SHOW RETENTION POLICIES ON my_db;
Error while planning query: This feature is not implemented: SHOW RETENTION POLICIES ON <database>

View File

@ -20,7 +20,10 @@ use crate::window::{
CUMULATIVE_SUM, DERIVATIVE, DIFFERENCE, MOVING_AVERAGE, NON_NEGATIVE_DERIVATIVE,
NON_NEGATIVE_DIFFERENCE, PERCENT_ROW_NUMBER,
};
use arrow::array::{StringBuilder, StringDictionaryBuilder};
use arrow::array::{
BooleanArray, DictionaryArray, Int32Array, Int64Array, StringArray, StringBuilder,
StringDictionaryBuilder,
};
use arrow::datatypes::{DataType, Field as ArrowField, Int32Type, Schema as ArrowSchema};
use arrow::record_batch::RecordBatch;
use chrono_tz::Tz;
@ -60,6 +63,7 @@ use influxdb_influxql_parser::show_field_keys::ShowFieldKeysStatement;
use influxdb_influxql_parser::show_measurements::{
ShowMeasurementsStatement, WithMeasurementClause,
};
use influxdb_influxql_parser::show_retention_policies::ShowRetentionPoliciesStatement;
use influxdb_influxql_parser::show_tag_keys::ShowTagKeysStatement;
use influxdb_influxql_parser::show_tag_values::{ShowTagValuesStatement, WithKeyClause};
use influxdb_influxql_parser::simple_from_clause::ShowFromClause;
@ -451,8 +455,8 @@ impl<'a> InfluxQLToLogicalPlan<'a> {
Statement::ShowMeasurements(show_measurements) => {
self.show_measurements_to_plan(*show_measurements)
}
Statement::ShowRetentionPolicies(_) => {
error::not_implemented("SHOW RETENTION POLICIES")
Statement::ShowRetentionPolicies(show_retention_policies) => {
self.show_retention_policies_to_plan(*show_retention_policies)
}
Statement::ShowTagKeys(show_tag_keys) => self.show_tag_keys_to_plan(*show_tag_keys),
Statement::ShowTagValues(show_tag_values) => {
@ -2828,6 +2832,76 @@ impl<'a> InfluxQLToLogicalPlan<'a> {
Ok(plan)
}
/// A limited implementation of SHOW RETENTION POLICIES that assumes
/// any database has a single, default, retention policy.
fn show_retention_policies_to_plan(
&self,
show_retention_policies: ShowRetentionPoliciesStatement,
) -> Result<LogicalPlan> {
if show_retention_policies.database.is_some() {
// This syntax is not yet handled.
return error::not_implemented("SHOW RETENTION POLICIES ON <database>");
}
let output_schema = Arc::new(ArrowSchema::new(vec![
ArrowField::new(
INFLUXQL_MEASUREMENT_COLUMN_NAME,
(&InfluxColumnType::Tag).into(),
false,
),
ArrowField::new(
"name",
(&InfluxColumnType::Field(InfluxFieldType::String)).into(),
false,
),
ArrowField::new(
"duration",
(&InfluxColumnType::Field(InfluxFieldType::String)).into(),
false,
),
ArrowField::new(
"shardGroupDuration",
(&InfluxColumnType::Field(InfluxFieldType::String)).into(),
false,
),
ArrowField::new(
"replicaN",
(&InfluxColumnType::Field(InfluxFieldType::Integer)).into(),
false,
),
ArrowField::new(
"default",
(&InfluxColumnType::Field(InfluxFieldType::Boolean)).into(),
false,
),
]));
let record_batch = RecordBatch::try_new(
Arc::clone(&output_schema),
vec![
Arc::new(DictionaryArray::try_new(
Int32Array::from(vec![0]),
Arc::new(StringArray::from(vec![Some("retention_policies")])),
)?),
Arc::new(StringArray::from(vec![Some("autogen")])),
Arc::new(StringArray::from(vec![Some("0s")])),
Arc::new(StringArray::from(vec![Some("168h0m0s")])),
Arc::new(Int64Array::from(vec![1])),
Arc::new(BooleanArray::from(vec![true])),
],
)?;
let table = Arc::new(MemTable::try_new(output_schema, vec![vec![record_batch]])?);
let plan = LogicalPlanBuilder::scan("retention policies", provider_as_source(table), None)?
.build()?;
let plan = plan_with_metadata(
plan,
&InfluxQlMetadata {
measurement_column_index: MEASUREMENT_COLUMN_INDEX,
tag_key_columns: vec![],
},
)?;
Ok(plan)
}
fn metadata_cutoff(&self) -> MetadataCutoff {
self.iox_ctx
.inner()
@ -3373,7 +3447,6 @@ mod test {
assert_snapshot!(plan("DELETE FROM foo"), @"This feature is not implemented: DELETE");
assert_snapshot!(plan("DROP MEASUREMENT foo"), @"This feature is not implemented: DROP MEASUREMENT");
assert_snapshot!(plan("SHOW DATABASES"), @"This feature is not implemented: SHOW DATABASES");
assert_snapshot!(plan("SHOW RETENTION POLICIES"), @"This feature is not implemented: SHOW RETENTION POLICIES");
}
mod metadata_queries {
@ -3732,6 +3805,16 @@ mod test {
TableScan: data [TIME:Boolean;N, bar:Dictionary(Int32, Utf8);N, bool_field:Boolean;N, f64_field:Float64;N, foo:Dictionary(Int32, Utf8);N, i64_field:Int64;N, mixedCase:Float64;N, str_field:Utf8;N, time:Timestamp(Nanosecond, None), with space:Float64;N]
"###);
}
#[test]
fn test_show_retention_policies() {
assert_snapshot!(plan("SHOW RETENTION POLICIES"), @r###"
TableScan: retention policies [iox::measurement:Dictionary(Int32, Utf8), name:Utf8, duration:Utf8, shardGroupDuration:Utf8, replicaN:Int64, default:Boolean]
"###);
assert_snapshot!(plan("SHOW RETENTION POLICIES ON my_db"), @r###"
This feature is not implemented: SHOW RETENTION POLICIES ON <database>
"###);
}
}
/// Tests to validate InfluxQL `SELECT` statements, where the projections do not matter,