Skip to content

Commit 7886ab1

Browse files
committed
feat: influxql support show measurements (#795)
* feat: influxql support show measurements * fix CI
1 parent e078de1 commit 7886ab1

17 files changed

+110
-19
lines changed

integration_tests/cases/common/dml/case_sensitive.result

+4
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,7 @@ DESC `CASE_SENSITIVE_TABLE1`;
9797

9898
Failed to execute query, err: Server(ServerError { code: 500, msg: "Failed to create plan, query: DESC `CASE_SENSITIVE_TABLE1`;. Caused by: Failed to create plan, err:Table not found, table:CASE_SENSITIVE_TABLE1" })
9999

100+
DROP TABLE IF EXISTS case_SENSITIVE_table1;
101+
102+
affected_rows: 0
103+

integration_tests/cases/common/dml/case_sensitive.sql

+2
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,5 @@ DESC CASE_SENSITIVE_TABLE1;
4949
DESC `case_SENSITIVE_table1`;
5050

5151
DESC `CASE_SENSITIVE_TABLE1`;
52+
53+
DROP TABLE IF EXISTS case_SENSITIVE_table1;

integration_tests/cases/common/dml/insert_mode.result

+4
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,7 @@ UInt64(0),Timestamp(2),UInt32(20),String("123"),UInt32(21),UInt32(22),UInt32(4),
201201
UInt64(0),Timestamp(3),UInt32(30),String("123"),UInt32(31),UInt32(32),UInt32(5),
202202

203203

204+
DROP TABLE IF EXISTS `03_dml_insert_mode_table4`;
205+
206+
affected_rows: 0
207+

integration_tests/cases/common/dml/insert_mode.sql

+2-1
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,5 @@ FROM
131131
ORDER BY
132132
`c1` ASC;
133133

134-
DROP TABLE `03_dml_insert_mode_table4`;
134+
135+
DROP TABLE IF EXISTS `03_dml_insert_mode_table4`;

integration_tests/cases/common/dml/issue-302.result

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
DROP TABLE IF EXISTS issue302;
2+
3+
affected_rows: 0
4+
15
CREATE TABLE `issue302` (`name` string TAG NULL, `value` double NOT NULL, `t` timestamp NOT NULL, TIMESTAMP KEY(t)) ENGINE=Analytic with (enable_ttl='false');
26

37
affected_rows: 0
@@ -12,3 +16,7 @@ issue302.t,COUNT(DISTINCT issue302.name),
1216
Timestamp(1651737067000),Int64(0),
1317

1418

19+
DROP TABLE IF EXISTS issue302;
20+
21+
affected_rows: 0
22+
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
DROP TABLE IF EXISTS issue302;
2+
13
CREATE TABLE `issue302` (`name` string TAG NULL, `value` double NOT NULL, `t` timestamp NOT NULL, TIMESTAMP KEY(t)) ENGINE=Analytic with (enable_ttl='false');
24

35
INSERT INTO issue302(t, value) VALUES(1651737067000, 100);
46

57
select `t`, count(distinct name) from issue302 group by `t`;
8+
9+
DROP TABLE IF EXISTS issue302;

integration_tests/cases/common/dml/issue-59.result

+4
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@ String("logical_plan"),String("Projection: issue59.id + Int64(1), COUNT(DISTINCT
2828
String("physical_plan"),String("ProjectionExec: expr=[issue59.id + Int64(1)@0 as issue59.id + Int64(1), COUNT(DISTINCT issue59.account)@1 as COUNT(DISTINCT issue59.account)]\n ProjectionExec: expr=[group_alias_0@0 as issue59.id + Int64(1), COUNT(alias1)@1 as COUNT(DISTINCT issue59.account)]\n AggregateExec: mode=FinalPartitioned, gby=[group_alias_0@0 as group_alias_0], aggr=[COUNT(alias1)]\n CoalesceBatchesExec: target_batch_size=8192\n RepartitionExec: partitioning=Hash([Column { name: \"group_alias_0\", index: 0 }], 8), input_partitions=8\n AggregateExec: mode=Partial, gby=[group_alias_0@0 as group_alias_0], aggr=[COUNT(alias1)]\n AggregateExec: mode=FinalPartitioned, gby=[group_alias_0@0 as group_alias_0, alias1@1 as alias1], aggr=[]\n CoalesceBatchesExec: target_batch_size=8192\n RepartitionExec: partitioning=Hash([Column { name: \"group_alias_0\", index: 0 }, Column { name: \"alias1\", index: 1 }], 8), input_partitions=8\n AggregateExec: mode=Partial, gby=[CAST(id@0 AS Int64) + 1 as group_alias_0, account@1 as alias1], aggr=[]\n ScanTable: table=issue59, parallelism=8, order=None, \n"),
2929

3030

31+
DROP TABLE IF EXISTS issue59;
32+
33+
affected_rows: 0
34+

integration_tests/cases/common/dml/issue-59.sql

+2
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ GROUP BY id+1;
1616
explain SELECT id+1, count(distinct(account))
1717
FROM issue59
1818
GROUP BY id+1;
19+
20+
DROP TABLE IF EXISTS issue59;

integration_tests/cases/common/dml/issue-637.result

+8
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,11 @@ tsid,t,double_filed,float_filed,str_field,var_field,u64_field,u32_field,u16_fiel
6363
UInt64(0),Timestamp(1651737067000),Double(100.0),Float(100.0),String("s"),Varbinary([118]),UInt64(100),UInt32(100),UInt16(100),UInt8(100),Int64(100),Int32(100),Int16(100),Int8(100),Boolean(false),
6464

6565

66+
DROP TABLE IF EXISTS issue637;
67+
68+
affected_rows: 0
69+
70+
DROP TABLE IF EXISTS issue637_1;
71+
72+
affected_rows: 0
73+

integration_tests/cases/common/dml/issue-637.sql

+4
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,7 @@ VALUES
4646
(1651737067000,100,100,"s","v",100,100,100,100,100,100,100,100,false);
4747

4848
SELECT * FROM `issue637_1`;
49+
50+
DROP TABLE IF EXISTS issue637;
51+
52+
DROP TABLE IF EXISTS issue637_1;

integration_tests/cases/env/local/influxql/basic.result

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ SELECT "level_description", location, water_level FROM "h2o_feet" where location
3434

3535
{"results":[{"statement_id":0,"series":[{"name":"h2o_feet","columns":["time","level_description","location","water_level"],"values":[[1439827200000,"below 3 feet","santa_monica",2.064],[1439827560000,"below 3 feet","santa_monica",2.116],[1439827620000,"below 3 feet","santa_monica",2.028]]}]}]}
3636

37+
-- SQLNESS ARG protocol=influxql
38+
show measurements;
39+
40+
{"results":[{"statement_id":0,"series":[{"name":"measurements","columns":["name"],"values":[["h2o_feet"]]}]}]}
41+
3742
DROP TABLE IF EXISTS `h2o_feet`;
3843

3944
affected_rows: 0

integration_tests/cases/env/local/influxql/basic.sql

+3
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,7 @@ SELECT * FROM "h2o_feet";
3232
-- SQLNESS ARG protocol=influxql
3333
SELECT "level_description", location, water_level FROM "h2o_feet" where location = 'santa_monica';
3434

35+
-- SQLNESS ARG protocol=influxql
36+
show measurements;
37+
3538
DROP TABLE IF EXISTS `h2o_feet`;

interpreters/src/show.rs

+31-11
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use regex::Regex;
1313
use snafu::{Backtrace, OptionExt, ResultExt, Snafu};
1414
use sql::{
1515
ast::ShowCreateObject,
16-
plan::{ShowCreatePlan, ShowPlan, ShowTablesPlan},
16+
plan::{QueryType, ShowCreatePlan, ShowPlan, ShowTablesPlan},
1717
};
1818

1919
use crate::{
@@ -127,17 +127,37 @@ impl ShowInterpreter {
127127
.map(|t| t.name().to_string())
128128
.collect::<Vec<_>>(),
129129
};
130-
let schema = DataSchema::new(vec![Field::new(
131-
SHOW_TABLES_COLUMN_SCHEMA,
132-
DataType::Utf8,
133-
false,
134-
)]);
135-
let record_batch = RecordBatch::try_new(
136-
Arc::new(schema),
137-
vec![Arc::new(StringArray::from(tables_names))],
138-
)
139-
.context(CreateRecordBatch)?;
140130

131+
let record_batch = match plan.query_type {
132+
QueryType::Sql => {
133+
let schema = DataSchema::new(vec![Field::new(
134+
SHOW_TABLES_COLUMN_SCHEMA,
135+
DataType::Utf8,
136+
false,
137+
)]);
138+
139+
RecordBatch::try_new(
140+
Arc::new(schema),
141+
vec![Arc::new(StringArray::from(tables_names))],
142+
)
143+
.context(CreateRecordBatch)?
144+
}
145+
QueryType::InfluxQL => {
146+
// TODO: refactor those constants
147+
let schema = DataSchema::new(vec![
148+
Field::new("ceresdb::measurement", DataType::Utf8, false),
149+
Field::new("name", DataType::Utf8, false),
150+
]);
151+
152+
let measurements = vec!["measurements".to_string(); tables_names.len()];
153+
let measurements = Arc::new(StringArray::from(measurements));
154+
RecordBatch::try_new(
155+
Arc::new(schema),
156+
vec![measurements, Arc::new(StringArray::from(tables_names))],
157+
)
158+
.context(CreateRecordBatch)?
159+
}
160+
};
141161
let record_batch = record_batch.try_into().context(ToCommonRecordType)?;
142162

143163
Ok(Output::Records(vec![record_batch]))

server/src/handlers/influxdb.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl From<&str> for Precision {
208208
/// Query string parameters for query api(by influxql)
209209
///
210210
/// It's derived from query string parameters of query described in
211-
/// doc of influxdb 1.8:
211+
/// doc of influxdb 1.8:
212212
/// https://docs.influxdata.com/influxdb/v1.8/tools/api/#query-string-parameters-1
213213
///
214214
/// NOTE:
@@ -311,6 +311,8 @@ impl InfluxqlResultBuilder {
311311
}
312312
);
313313

314+
// Query like `show measurements`, there will be not timestamp.
315+
let has_timestamp = column_schemas.iter().any(|c| c.data_type.is_timestamp());
314316
// Find the tags part and columns part from schema.
315317
let mut group_by_col_idxs = Vec::new();
316318
let mut value_col_idxs = Vec::new();
@@ -324,7 +326,7 @@ impl InfluxqlResultBuilder {
324326
});
325327

326328
// The group by tags will be placed after measurement and before time column.
327-
let mut searching_group_by_tags = true;
329+
let mut searching_group_by_tags = has_timestamp;
328330
for (idx, col) in col_iter {
329331
if col.data_type.is_timestamp() {
330332
searching_group_by_tags = false;

sql/src/influxql/planner.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ use influxql_logical_planner::planner::InfluxQLToLogicalPlan;
99
use influxql_parser::{
1010
common::{MeasurementName, QualifiedMeasurementName},
1111
select::{MeasurementSelection, SelectStatement},
12+
show_measurements::ShowMeasurementsStatement,
1213
statement::Statement as InfluxqlStatement,
1314
};
1415
use snafu::{ensure, ResultExt};
1516

1617
use crate::{
1718
influxql::{error::*, provider::InfluxSchemaProviderImpl},
18-
plan::{Plan, QueryPlan},
19+
plan::{Plan, QueryPlan, QueryType, ShowPlan, ShowTablesPlan},
1920
provider::{ContextProviderAdapter, MetaProvider},
2021
};
2122

@@ -36,15 +37,15 @@ impl<'a, P: MetaProvider> Planner<'a, P> {
3637
/// the [InfluxqlStatement] will be converted to [SqlStatement] first,
3738
/// and build plan then.
3839
pub fn statement_to_plan(self, stmt: InfluxqlStatement) -> Result<Plan> {
39-
match &stmt {
40+
match stmt {
4041
InfluxqlStatement::Select(_) => self.select_to_plan(stmt),
42+
InfluxqlStatement::ShowMeasurements(stmt) => self.show_measurements_to_plan(*stmt),
4143
InfluxqlStatement::CreateDatabase(_)
4244
| InfluxqlStatement::ShowDatabases(_)
4345
| InfluxqlStatement::ShowRetentionPolicies(_)
4446
| InfluxqlStatement::ShowTagKeys(_)
4547
| InfluxqlStatement::ShowTagValues(_)
4648
| InfluxqlStatement::ShowFieldKeys(_)
47-
| InfluxqlStatement::ShowMeasurements(_)
4849
| InfluxqlStatement::Delete(_)
4950
| InfluxqlStatement::DropMeasurement(_)
5051
| InfluxqlStatement::Explain(_) => Unimplemented {
@@ -54,7 +55,16 @@ impl<'a, P: MetaProvider> Planner<'a, P> {
5455
}
5556
}
5657

57-
pub fn select_to_plan(self, stmt: InfluxqlStatement) -> Result<Plan> {
58+
// TODO: support offset/limit/match in stmt
59+
fn show_measurements_to_plan(self, _stmt: ShowMeasurementsStatement) -> Result<Plan> {
60+
let plan = ShowTablesPlan {
61+
pattern: None,
62+
query_type: QueryType::InfluxQL,
63+
};
64+
Ok(Plan::Show(ShowPlan::ShowTablesPlan(plan)))
65+
}
66+
67+
fn select_to_plan(self, stmt: InfluxqlStatement) -> Result<Plan> {
5868
if let InfluxqlStatement::Select(select_stmt) = &stmt {
5969
check_select_statement(select_stmt)?;
6070
} else {

sql/src/plan.rs

+7
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,17 @@ pub struct ShowCreatePlan {
161161
pub obj_type: ShowCreateObject,
162162
}
163163

164+
#[derive(Debug, PartialEq, Eq)]
165+
pub enum QueryType {
166+
Sql,
167+
InfluxQL,
168+
}
169+
164170
#[derive(Debug, PartialEq, Eq)]
165171
pub struct ShowTablesPlan {
166172
/// Like pattern
167173
pub pattern: Option<String>,
174+
pub query_type: QueryType,
168175
}
169176

170177
#[derive(Debug)]

sql/src/planner.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ use crate::{
5555
partition::PartitionParser,
5656
plan::{
5757
AlterTableOperation, AlterTablePlan, CreateTablePlan, DescribeTablePlan, DropTablePlan,
58-
ExistsTablePlan, InsertPlan, Plan, QueryPlan, ShowCreatePlan, ShowPlan, ShowTablesPlan,
58+
ExistsTablePlan, InsertPlan, Plan, QueryPlan, QueryType, ShowCreatePlan, ShowPlan,
59+
ShowTablesPlan,
5960
},
6061
promql::{ColumnNames, Expr as PromExpr},
6162
provider::{ContextProviderAdapter, MetaProvider},
@@ -992,6 +993,7 @@ impl<'a, P: MetaProvider> PlannerDelegate<'a, P> {
992993
fn show_tables_to_plan(&self, show_tables: ShowTables) -> Result<Plan> {
993994
let plan = ShowTablesPlan {
994995
pattern: show_tables.pattern,
996+
query_type: QueryType::Sql,
995997
};
996998
Ok(Plan::Show(ShowPlan::ShowTablesPlan(plan)))
997999
}
@@ -2193,6 +2195,7 @@ mod tests {
21932195
ShowTablesPlan(
21942196
ShowTablesPlan {
21952197
pattern: None,
2198+
query_type: Sql,
21962199
},
21972200
),
21982201
)"#,

0 commit comments

Comments
 (0)