mirror of
https://github.com/GreptimeTeam/greptimedb.git
synced 2026-05-25 09:20:40 +00:00
feat: add cursor statements (#5094)
* feat: add sql parsers for cursor operations * feat: cursor operator * feat: implement RecordBatchStreamCursor * feat: implement cursor storage and execution * test: add tests * chore: update docstring * feat: add a temporary sql rewrite for cast in limit this issue is described in #5097 * test: add more sql for cursor integration test * feat: reject non-select query for cursor statement * refactor: address review issues * test: add empty result case * feat: address review comments
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -112,6 +113,13 @@ pub(crate) fn process<'a>(query: &str, query_ctx: QueryContextRef) -> Option<Vec
|
||||
}
|
||||
}
|
||||
|
||||
static LIMIT_CAST_PATTERN: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new("(?i)(LIMIT\\s+\\d+)::bigint").unwrap());
|
||||
pub(crate) fn rewrite_sql(query: &str) -> Cow<'_, str> {
|
||||
//TODO(sunng87): remove this when we upgraded datafusion to 43 or newer
|
||||
LIMIT_CAST_PATTERN.replace_all(query, "$1")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use session::context::{QueryContext, QueryContextRef};
|
||||
@@ -195,4 +203,13 @@ mod test {
|
||||
assert!(process("SHOW TABLES ", query_context.clone()).is_none());
|
||||
assert!(process("SET TIME_ZONE=utc ", query_context.clone()).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rewrite() {
|
||||
let sql = "SELECT * FROM number LIMIT 1::bigint";
|
||||
let sql2 = "SELECT * FROM number limit 1::BIGINT";
|
||||
|
||||
assert_eq!("SELECT * FROM number LIMIT 1", rewrite_sql(sql));
|
||||
assert_eq!("SELECT * FROM number limit 1", rewrite_sql(sql2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,9 @@ impl SimpleQueryHandler for PostgresServerHandlerInner {
|
||||
return Ok(vec![Response::EmptyQuery]);
|
||||
}
|
||||
|
||||
let query = fixtures::rewrite_sql(query);
|
||||
let query = query.as_ref();
|
||||
|
||||
if let Some(resps) = fixtures::process(query, query_ctx.clone()) {
|
||||
send_warning_opt(client, query_ctx).await?;
|
||||
Ok(resps)
|
||||
@@ -229,6 +232,9 @@ impl QueryParser for DefaultQueryParser {
|
||||
});
|
||||
}
|
||||
|
||||
let sql = fixtures::rewrite_sql(sql);
|
||||
let sql = sql.as_ref();
|
||||
|
||||
let mut stmts =
|
||||
ParserContext::create_with_dialect(sql, &PostgreSqlDialect {}, ParseOptions::default())
|
||||
.map_err(|e| PgWireError::ApiError(Box::new(e)))?;
|
||||
|
||||
Reference in New Issue
Block a user