Add support for PRINT statement for SQL Server (#1811)

This commit is contained in:
Andrew Harper 2025-04-18 02:59:39 -04:00 committed by GitHub
parent 81d8909e00
commit 4a487290ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 47 additions and 1 deletions

View file

@ -4054,6 +4054,12 @@ pub enum Statement {
arguments: Vec<Expr>,
options: Vec<RaisErrorOption>,
},
/// ```sql
/// PRINT msg_str | @local_variable | string_expr
/// ```
///
/// See: <https://learn.microsoft.com/en-us/sql/t-sql/statements/print-transact-sql>
Print(PrintStatement),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
@ -5745,7 +5751,7 @@ impl fmt::Display for Statement {
}
Ok(())
}
Statement::Print(s) => write!(f, "{s}"),
Statement::List(command) => write!(f, "LIST {command}"),
Statement::Remove(command) => write!(f, "REMOVE {command}"),
}
@ -9211,6 +9217,19 @@ pub enum CopyIntoSnowflakeKind {
Location,
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub struct PrintStatement {
pub message: Box<Expr>,
}
impl fmt::Display for PrintStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PRINT {}", self.message)
}
}
#[cfg(test)]
mod tests {
use super::*;

View file

@ -519,6 +519,7 @@ impl Spanned for Statement {
Statement::UNLISTEN { .. } => Span::empty(),
Statement::RenameTable { .. } => Span::empty(),
Statement::RaisError { .. } => Span::empty(),
Statement::Print { .. } => Span::empty(),
Statement::List(..) | Statement::Remove(..) => Span::empty(),
}
}

View file

@ -686,6 +686,7 @@ define_keywords!(
PRESERVE,
PREWHERE,
PRIMARY,
PRINT,
PRIOR,
PRIVILEGES,
PROCEDURE,

View file

@ -617,6 +617,7 @@ impl<'a> Parser<'a> {
}
// `COMMENT` is snowflake specific https://docs.snowflake.com/en/sql-reference/sql/comment
Keyword::COMMENT if self.dialect.supports_comment_on() => self.parse_comment(),
Keyword::PRINT => self.parse_print(),
_ => self.expected("an SQL statement", next_token),
},
Token::LParen => {
@ -15056,6 +15057,13 @@ impl<'a> Parser<'a> {
}
}
/// Parse [Statement::Print]
fn parse_print(&mut self) -> Result<Statement, ParserError> {
Ok(Statement::Print(PrintStatement {
message: Box::new(self.parse_expr()?),
}))
}
/// Consume the parser and return its underlying token buffer
pub fn into_tokens(self) -> Vec<TokenWithSpan> {
self.tokens

View file

@ -2053,3 +2053,20 @@ fn parse_drop_trigger() {
}
);
}
#[test]
fn parse_print() {
let print_string_literal = "PRINT 'Hello, world!'";
let print_stmt = ms().verified_stmt(print_string_literal);
assert_eq!(
print_stmt,
Statement::Print(PrintStatement {
message: Box::new(Expr::Value(
(Value::SingleQuotedString("Hello, world!".to_string())).with_empty_span()
)),
})
);
let _ = ms().verified_stmt("PRINT N'Hello, ⛄️!'");
let _ = ms().verified_stmt("PRINT @my_variable");
}