Skip to content

Commit

Permalink
Merge pull request #4894 from cadl/issue-4860
Browse files Browse the repository at this point in the history
ISSUE-4860: fix empty query
  • Loading branch information
BohuTANG authored Apr 17, 2022
2 parents a0b9686 + 90ba0dd commit d8d9bf5
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 7 deletions.
53 changes: 53 additions & 0 deletions query/src/interpreters/interpreter_empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 Datafuse Labs.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::sync::Arc;

use common_datavalues::prelude::*;
use common_exception::Result;
use common_planners::EmptyPlan;
use common_streams::DataBlockStream;
use common_streams::SendableDataBlockStream;

use crate::interpreters::Interpreter;
use crate::interpreters::InterpreterPtr;
use crate::sessions::QueryContext;

// EmptyInterpreter is a Empty interpreter to execute nothing.
// Such as the query '/*!40101*/', it makes the front-end (e.g. MySQL handler) no need check the EmptyPlan or not.
pub struct EmptyInterpreter {}

impl EmptyInterpreter {
pub fn try_create(_ctx: Arc<QueryContext>, _plan: EmptyPlan) -> Result<InterpreterPtr> {
Ok(Arc::new(EmptyInterpreter {}))
}
}

#[async_trait::async_trait]
impl Interpreter for EmptyInterpreter {
fn name(&self) -> &str {
"EmptyInterpreter"
}

async fn execute(
&self,
_input_stream: Option<SendableDataBlockStream>,
) -> Result<SendableDataBlockStream> {
Ok(Box::pin(DataBlockStream::create(
Arc::new(DataSchema::empty()),
None,
vec![],
)))
}
}
2 changes: 2 additions & 0 deletions query/src/interpreters/interpreter_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ use crate::interpreters::DropTableInterpreter;
use crate::interpreters::DropUserInterpreter;
use crate::interpreters::DropUserUDFInterpreter;
use crate::interpreters::DropViewInterpreter;
use crate::interpreters::EmptyInterpreter;
use crate::interpreters::ExplainInterpreter;
use crate::interpreters::GrantPrivilegeInterpreter;
use crate::interpreters::GrantRoleInterpreter;
Expand Down Expand Up @@ -172,6 +173,7 @@ impl InterpreterFactory {
PlanNode::UseDatabase(v) => UseDatabaseInterpreter::try_create(ctx_clone, v),
PlanNode::Kill(v) => KillInterpreter::try_create(ctx_clone, v),
PlanNode::SetVariable(v) => SettingInterpreter::try_create(ctx_clone, v),
PlanNode::Empty(v) => EmptyInterpreter::try_create(ctx_clone, v),

_ => Result::Err(ErrorCode::UnknownTypeOfQuery(format!(
"Can't get the interpreter by plan:{}",
Expand Down
2 changes: 2 additions & 0 deletions query/src/interpreters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod interpreter_copy;
mod interpreter_database_create;
mod interpreter_database_drop;
mod interpreter_database_show_create;
mod interpreter_empty;
mod interpreter_explain;
mod interpreter_factory;
mod interpreter_factory_interceptor;
Expand Down Expand Up @@ -76,6 +77,7 @@ pub use interpreter_copy::CopyInterpreter;
pub use interpreter_database_create::CreateDatabaseInterpreter;
pub use interpreter_database_drop::DropDatabaseInterpreter;
pub use interpreter_database_show_create::ShowCreateDatabaseInterpreter;
pub use interpreter_empty::EmptyInterpreter;
pub use interpreter_explain::ExplainInterpreter;
pub use interpreter_factory::InterpreterFactory;
pub use interpreter_factory_interceptor::InterceptorInterpreter;
Expand Down
3 changes: 2 additions & 1 deletion query/src/sql/plan_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::sync::Arc;

use common_exception::ErrorCode;
use common_exception::Result;
use common_planners::EmptyPlan;
use common_planners::ExplainPlan;
use common_planners::Expression;
use common_planners::PlanBuilder;
Expand Down Expand Up @@ -54,7 +55,7 @@ impl PlanParser {
ctx: Arc<QueryContext>,
) -> Result<PlanNode> {
if statements.is_empty() {
return Err(ErrorCode::SyntaxException("Empty query"));
return Ok(PlanNode::Empty(EmptyPlan::create()));
} else if statements.len() > 1 {
return Err(ErrorCode::SyntaxException("Only support single query"));
}
Expand Down
60 changes: 60 additions & 0 deletions query/tests/it/interpreters/interpreter_empty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright 2021 Datafuse Labs.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use common_base::tokio;
use common_exception::Result;
use databend_query::interpreters::*;
use databend_query::sql::*;
use futures::TryStreamExt;
use pretty_assertions::assert_eq;

#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_empty_interpreter() -> Result<()> {
common_tracing::init_default_ut_tracing();
let ctx = crate::tests::create_query_context().await?;

{
let query = "/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */";
let plan = PlanParser::parse(ctx.clone(), query).await?;
let executor = InterpreterFactory::get(ctx.clone(), plan)?;
assert_eq!(executor.name(), "EmptyInterpreter");

let stream = executor.execute(None).await?;
let result = stream.try_collect::<Vec<_>>().await;
assert!(result.is_ok())
}

{
let query = "/*!40101*/select number from numbers_mt(1)";
let plan = PlanParser::parse(ctx.clone(), query).await?;
let executor = InterpreterFactory::get(ctx.clone(), plan)?;
assert_eq!(executor.name(), "SelectInterpreter");

let stream = executor.execute(None).await?;
let result = stream.try_collect::<Vec<_>>().await?;
let block = &result[0];
assert_eq!(block.num_columns(), 1);

let expected = vec![
"+--------+",
"| number |",
"+--------+",
"| 0 |",
"+--------+",
];
common_datablocks::assert_blocks_sorted_eq(expected, result.as_slice());
}

Ok(())
}
1 change: 1 addition & 0 deletions query/tests/it/interpreters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod interpreter_call;
mod interpreter_database_create;
mod interpreter_database_drop;
mod interpreter_database_show_create;
mod interpreter_empty;
mod interpreter_explain;
mod interpreter_factory_interceptor;
mod interpreter_insert;
Expand Down
12 changes: 6 additions & 6 deletions query/tests/it/servers/http/clickhouse_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,6 @@ macro_rules! assert_ok {
async fn test_select() -> PoemResult<()> {
let server = Server::new();

{
let (status, body) = server.get("").await;
assert_eq!(status, StatusCode::BAD_REQUEST);
assert_error!(body, "Empty query");
}

{
let (status, body) = server.get("bad sql").await;
assert_eq!(status, StatusCode::BAD_REQUEST);
Expand All @@ -69,6 +63,12 @@ async fn test_select() -> PoemResult<()> {
assert_error!(body, "sql parser error");
}

{
let (status, body) = server.get("").await;
assert_eq!(status, StatusCode::OK);
assert_eq!(&body, "");
}

{
let (status, body) = server.get("select 1").await;
assert_eq!(status, StatusCode::OK);
Expand Down
3 changes: 3 additions & 0 deletions tests/suites/0_stateless/03_dml/03_0019_select_empty.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
0
1
0
3 changes: 3 additions & 0 deletions tests/suites/0_stateless/03_dml/03_0019_select_empty.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*!40101*/select number from numbers_mt(2);
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101*/select number from numbers_mt(1);

0 comments on commit d8d9bf5

Please sign in to comment.