From eb21c72c449a01066af13fc5acf4d5e5a80cc720 Mon Sep 17 00:00:00 2001 From: August Date: Fri, 16 Jun 2023 15:24:06 +0800 Subject: [PATCH 1/3] feat: add system function user --- src/frontend/src/binder/expr/function.rs | 5 +++++ src/frontend/src/binder/expr/mod.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/binder/expr/function.rs b/src/frontend/src/binder/expr/function.rs index 309b18d912c54..e31c24e38236b 100644 --- a/src/frontend/src/binder/expr/function.rs +++ b/src/frontend/src/binder/expr/function.rs @@ -728,6 +728,11 @@ impl Binder { binder.auth_context.user_name.clone(), )) }))), + ("user", guard_by_len(0, raw(|binder, _inputs| { + Ok(ExprImpl::literal_varchar( + binder.auth_context.user_name.clone(), + )) + }))), ("pg_get_userbyid", guard_by_len(1, raw(|binder, inputs|{ let input = &inputs[0]; let bound_query = binder.bind_get_user_by_id_select(input)?; diff --git a/src/frontend/src/binder/expr/mod.rs b/src/frontend/src/binder/expr/mod.rs index fabf64289d371..94b1a701191e3 100644 --- a/src/frontend/src/binder/expr/mod.rs +++ b/src/frontend/src/binder/expr/mod.rs @@ -87,7 +87,7 @@ impl Binder { Expr::Row(exprs) => self.bind_row(exprs), // input ref Expr::Identifier(ident) => { - if ["session_user", "current_schema", "current_timestamp"] + if ["session_user", "user", "current_schema", "current_timestamp"] .iter() .any(|e| ident.real_value().as_str() == *e) { From d43601f3a6da7176f843393a7c65b76fec3a1b13 Mon Sep 17 00:00:00 2001 From: August Date: Fri, 16 Jun 2023 15:37:38 +0800 Subject: [PATCH 2/3] fmt --- src/frontend/src/binder/expr/mod.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/frontend/src/binder/expr/mod.rs b/src/frontend/src/binder/expr/mod.rs index 94b1a701191e3..8804e295b348b 100644 --- a/src/frontend/src/binder/expr/mod.rs +++ b/src/frontend/src/binder/expr/mod.rs @@ -87,9 +87,14 @@ impl Binder { Expr::Row(exprs) => self.bind_row(exprs), // input ref Expr::Identifier(ident) => { - if ["session_user", "user", "current_schema", "current_timestamp"] - .iter() - .any(|e| ident.real_value().as_str() == *e) + if [ + "session_user", + "user", + "current_schema", + "current_timestamp", + ] + .iter() + .any(|e| ident.real_value().as_str() == *e) { // Rewrite a system variable to a function call, e.g. `SELECT current_schema;` // will be rewritten to `SELECT current_schema();`. From e3cbe0cc7e3b10f71a4ff1a8d053ed1d844fe00b Mon Sep 17 00:00:00 2001 From: August Date: Mon, 19 Jun 2023 15:23:45 +0800 Subject: [PATCH 3/3] add comments --- src/frontend/src/binder/expr/function.rs | 50 +++++++++++++++++++----- src/frontend/src/binder/expr/mod.rs | 12 ++---- 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/frontend/src/binder/expr/function.rs b/src/frontend/src/binder/expr/function.rs index e31c24e38236b..e4db03386a6bf 100644 --- a/src/frontend/src/binder/expr/function.rs +++ b/src/frontend/src/binder/expr/function.rs @@ -42,6 +42,16 @@ use crate::expr::{ }; use crate::utils::Condition; +// Defines system functions that without args, ref: https://www.postgresql.org/docs/current/functions-info.html +pub const SYS_FUNCTION_WITHOUT_ARGS: &[&str] = &[ + "session_user", + "user", + "current_user", + "current_role", + "current_schema", + "current_timestamp", +]; + impl Binder { pub(in crate::binder) fn bind_function(&mut self, f: Function) -> Result { let function_name = match f.name.0.as_slice() { @@ -477,6 +487,32 @@ impl Binder { }) } + // `SESSION_USER` is the user name of the user that is connected to the database. + fn session_user() -> Handle { + guard_by_len( + 0, + raw(|binder, _inputs| { + Ok(ExprImpl::literal_varchar( + binder.auth_context.user_name.clone(), + )) + }), + ) + } + + // `CURRENT_USER` is the user name of the user that is executing the command, + // `CURRENT_ROLE`, `USER` are synonyms for `CURRENT_USER`. Since we don't support + // `SET ROLE xxx` for now, they will all returns session user name. + fn current_user() -> Handle { + guard_by_len( + 0, + raw(|binder, _inputs| { + Ok(ExprImpl::literal_varchar( + binder.auth_context.user_name.clone(), + )) + }), + ) + } + static HANDLES: LazyLock> = LazyLock::new(|| { [ ( @@ -723,16 +759,10 @@ impl Binder { DataType::Varchar, )) })), - ("session_user", guard_by_len(0, raw(|binder, _inputs| { - Ok(ExprImpl::literal_varchar( - binder.auth_context.user_name.clone(), - )) - }))), - ("user", guard_by_len(0, raw(|binder, _inputs| { - Ok(ExprImpl::literal_varchar( - binder.auth_context.user_name.clone(), - )) - }))), + ("session_user", session_user()), + ("current_role", current_user()), + ("current_user", current_user()), + ("user", current_user()), ("pg_get_userbyid", guard_by_len(1, raw(|binder, inputs|{ let input = &inputs[0]; let bound_query = binder.bind_get_user_by_id_select(input)?; diff --git a/src/frontend/src/binder/expr/mod.rs b/src/frontend/src/binder/expr/mod.rs index 8804e295b348b..964137d425758 100644 --- a/src/frontend/src/binder/expr/mod.rs +++ b/src/frontend/src/binder/expr/mod.rs @@ -22,6 +22,7 @@ use risingwave_sqlparser::ast::{ TrimWhereField, UnaryOperator, }; +use crate::binder::expr::function::SYS_FUNCTION_WITHOUT_ARGS; use crate::binder::Binder; use crate::expr::{Expr as _, ExprImpl, ExprType, FunctionCall, Parameter, SubqueryKind}; @@ -87,14 +88,9 @@ impl Binder { Expr::Row(exprs) => self.bind_row(exprs), // input ref Expr::Identifier(ident) => { - if [ - "session_user", - "user", - "current_schema", - "current_timestamp", - ] - .iter() - .any(|e| ident.real_value().as_str() == *e) + if SYS_FUNCTION_WITHOUT_ARGS + .iter() + .any(|e| ident.real_value().as_str() == *e) { // Rewrite a system variable to a function call, e.g. `SELECT current_schema;` // will be rewritten to `SELECT current_schema();`.