Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4263,6 +4263,14 @@ pub enum Statement {
/// ```
/// [Redshift](https://docs.aws.amazon.com/redshift/latest/dg/r_VACUUM_command.html)
Vacuum(VacuumStatement),
/// Restore the value of a run-time parameter to the default value.
///
/// ```sql
/// RESET configuration_parameter;
/// RESET ALL;
/// ```
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-reset.html)
Reset(ResetStatement),
}

impl From<Analyze> for Statement {
Expand Down Expand Up @@ -5757,6 +5765,7 @@ impl fmt::Display for Statement {
Statement::AlterSchema(s) => write!(f, "{s}"),
Statement::Vacuum(s) => write!(f, "{s}"),
Statement::AlterUser(s) => write!(f, "{s}"),
Statement::Reset(s) => write!(f, "{s}"),
}
}
}
Expand Down Expand Up @@ -10519,6 +10528,38 @@ impl fmt::Display for VacuumStatement {
}
}

/// Variants of the RESET statement
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum Reset {
/// Resets all session parameters to their default values.
ALL,

/// Resets a specific session parameter to its default value.
ConfigurationParameter(ObjectName),
}

/// Resets a session parameter to its default value.
/// ```sql
/// RESET { ALL | <configuration_parameter> }
/// ```
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct ResetStatement {
pub reset: Reset,
}

impl fmt::Display for ResetStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.reset {
Reset::ALL => write!(f, "RESET ALL"),
Reset::ConfigurationParameter(param) => write!(f, "RESET {}", param),
}
}
}

impl From<Set> for Statement {
fn from(s: Set) -> Self {
Self::Set(s)
Expand Down Expand Up @@ -10759,6 +10800,12 @@ impl From<VacuumStatement> for Statement {
}
}

impl From<ResetStatement> for Statement {
fn from(r: ResetStatement) -> Self {
Self::Reset(r)
}
}

#[cfg(test)]
mod tests {
use crate::tokenizer::Location;
Expand Down
1 change: 1 addition & 0 deletions src/ast/spans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ impl Spanned for Statement {
Statement::AlterSchema(s) => s.span(),
Statement::Vacuum(..) => Span::empty(),
Statement::AlterUser(..) => Span::empty(),
Statement::Reset(..) => Span::empty(),
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/dialect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,17 @@ pub trait Dialect: Debug + Any {
fn supports_semantic_view_table_factor(&self) -> bool {
false
}

/// Returns true if the dialect supports the `RESET` statement
/// for resetting session variables.
///
/// ```sql
/// RESET configuration_parameter;
/// RESET ALL;
/// ```
fn supports_reset(&self) -> bool {
false
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Returns true if the dialect supports the `RESET` statement
/// for resetting session variables.
///
/// ```sql
/// RESET configuration_parameter;
/// RESET ALL;
/// ```
fn supports_reset(&self) -> bool {
false
}

I think we can let the parser always accept the statement if it shows up, without considering the dialect

Copy link
Author

@watford-ep watford-ep Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can do. I think out of the list of dialects only ANSI, sqlite, and Hive lack support (Hive SQL doesn't take a parameter).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the ticket to include exactly which dialects support RESET, and its a bit touch and go. Right now this seems reasonable (in that it accepts a very reasonable use, though not strictly correct for all dialects).

}

/// This represents the operators for which precedence must be defined
Expand Down
7 changes: 7 additions & 0 deletions src/dialect/postgresql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,4 +280,11 @@ impl Dialect for PostgreSqlDialect {
fn supports_interval_options(&self) -> bool {
true
}

/// Postgres supports the `RESET` statement for resetting session variables.
///
/// [PostgreSQL](https://www.postgresql.org/docs/current/sql-reset.html)
fn supports_reset(&self) -> bool {
true
}
}
38 changes: 38 additions & 0 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@ impl<'a> Parser<'a> {
self.prev_token();
self.parse_vacuum()
}
Keyword::RESET if self.dialect.supports_reset() => self.parse_reset(),
_ => self.expected("an SQL statement", next_token),
},
Token::LParen => {
Expand Down Expand Up @@ -17723,6 +17724,18 @@ impl<'a> Parser<'a> {
_ => self.expected("expected option value", self.peek_token()),
}
}

fn parse_reset(&mut self) -> Result<Statement, ParserError> {
// RESET { ALL | <configuration_parameter> }
if self.parse_keyword(Keyword::ALL) {
return Ok(Statement::Reset(ResetStatement { reset: Reset::ALL }));
}

let obj = self.parse_object_name(false)?;
Ok(Statement::Reset(ResetStatement {
reset: Reset::ConfigurationParameter(obj),
}))
}
}

fn maybe_prefixed_expr(expr: Expr, prefix: Option<Ident>) -> Expr {
Expand Down Expand Up @@ -18529,4 +18542,29 @@ mod tests {
assert!(Parser::parse_sql(&GenericDialect, &sql).is_err());
}
}

#[test]
fn test_reset_all() {
let sql = "RESET ALL";
let ast = Parser::parse_sql(&PostgreSqlDialect {}, sql).unwrap();
assert_eq!(
ast,
vec![Statement::Reset(ResetStatement { reset: Reset::ALL })]
);
}

#[test]
fn test_reset_parameter() {
for w in ["parameter_name", "extension.parameter_name"] {
let sql = format!("RESET {w}");
let parts = w.split(".").map(|s| s.into()).collect::<Vec<Ident>>();
let ast = Parser::parse_sql(&PostgreSqlDialect {}, &sql).unwrap();
assert_eq!(
ast,
vec![Statement::Reset(ResetStatement {
reset: Reset::ConfigurationParameter(ObjectName::from(parts))
})]
);
}
}
}
27 changes: 27 additions & 0 deletions tests/sqlparser_postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6652,3 +6652,30 @@ fn parse_foreign_key_match_with_actions() {

pg_and_generic().verified_stmt(sql);
}

#[test]
fn parse_reset_statement() {
match pg().verified_stmt("RESET some_parameter") {
Statement::Reset(ResetStatement { reset }) => match reset {
Reset::ConfigurationParameter(o) => {
assert_eq!(o, ObjectName::from(vec!["some_parameter".into()]))
}
_ => unreachable!(),
},
_ => unreachable!(),
}
match pg().verified_stmt("RESET some_extension.some_parameter") {
Statement::Reset(ResetStatement { reset }) => match reset {
Reset::ConfigurationParameter(o) => assert_eq!(
o,
ObjectName::from(vec!["some_extension".into(), "some_parameter".into()])
),
_ => unreachable!(),
},
_ => unreachable!(),
}
match pg().verified_stmt("RESET ALL") {
Statement::Reset(ResetStatement { reset }) => assert_eq!(reset, Reset::ALL),
_ => unreachable!(),
}
}