@@ -1422,6 +1422,211 @@ pub enum Password {
14221422 NullPassword ,
14231423}
14241424
1425+ /// Represents an expression assignment within a variable `DECLARE` statement.
1426+ ///
1427+ /// Examples:
1428+ /// ```sql
1429+ /// DECLARE variable_name := 42
1430+ /// DECLARE variable_name DEFAULT 42
1431+ /// ```
1432+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1433+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1434+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1435+ pub enum DeclareAssignment {
1436+ /// Plain expression specified.
1437+ Expr ( Box < Expr > ) ,
1438+
1439+ /// Expression assigned via the `DEFAULT` keyword
1440+ Default ( Box < Expr > ) ,
1441+
1442+ /// Expression assigned via the `:=` syntax
1443+ ///
1444+ /// Example:
1445+ /// ```sql
1446+ /// DECLARE variable_name := 42;
1447+ /// ```
1448+ DuckAssignment ( Box < Expr > ) ,
1449+
1450+ /// Expression via the `FOR` keyword
1451+ ///
1452+ /// Example:
1453+ /// ```sql
1454+ /// DECLARE c1 CURSOR FOR res
1455+ /// ```
1456+ For ( Box < Expr > ) ,
1457+ }
1458+
1459+ impl fmt:: Display for DeclareAssignment {
1460+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1461+ match self {
1462+ DeclareAssignment :: Expr ( expr) => {
1463+ write ! ( f, "{expr}" )
1464+ }
1465+ DeclareAssignment :: Default ( expr) => {
1466+ write ! ( f, "DEFAULT {expr}" )
1467+ }
1468+ DeclareAssignment :: DuckAssignment ( expr) => {
1469+ write ! ( f, ":= {expr}" )
1470+ }
1471+ DeclareAssignment :: For ( expr) => {
1472+ write ! ( f, "FOR {expr}" )
1473+ }
1474+ }
1475+ }
1476+ }
1477+
1478+ /// Represents the type of a `DECLARE` statement.
1479+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1480+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1481+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1482+ pub enum DeclareType {
1483+ /// Cursor variable type. e.g. [Snowflake] [Postgres]
1484+ ///
1485+ /// [Snowflake]: https://docs.snowflake.com/en/developer-guide/snowflake-scripting/cursors#declaring-a-cursor
1486+ /// [Postgres]: https://www.postgresql.org/docs/current/plpgsql-cursors.html
1487+ Cursor ,
1488+
1489+ /// Result set variable type. [Snowflake]
1490+ ///
1491+ /// Syntax:
1492+ /// ```text
1493+ /// <resultset_name> RESULTSET [ { DEFAULT | := } ( <query> ) ] ;
1494+ /// ```
1495+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#resultset-declaration-syntax
1496+ ResultSet ,
1497+
1498+ /// Exception declaration syntax. [Snowflake]
1499+ ///
1500+ /// Syntax:
1501+ /// ```text
1502+ /// <exception_name> EXCEPTION [ ( <exception_number> , '<exception_message>' ) ] ;
1503+ /// ```
1504+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare#exception-declaration-syntax
1505+ Exception ,
1506+ }
1507+
1508+ impl fmt:: Display for DeclareType {
1509+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1510+ match self {
1511+ DeclareType :: Cursor => {
1512+ write ! ( f, "CURSOR" )
1513+ }
1514+ DeclareType :: ResultSet => {
1515+ write ! ( f, "RESULTSET" )
1516+ }
1517+ DeclareType :: Exception => {
1518+ write ! ( f, "EXCEPTION" )
1519+ }
1520+ }
1521+ }
1522+ }
1523+
1524+ /// A `DECLARE` statement.
1525+ /// [Postgres] [Snowflake] [BigQuery]
1526+ ///
1527+ /// Examples:
1528+ /// ```sql
1529+ /// DECLARE variable_name := 42
1530+ /// DECLARE liahona CURSOR FOR SELECT * FROM films;
1531+ /// ```
1532+ ///
1533+ /// [Postgres]: https://www.postgresql.org/docs/current/sql-declare.html
1534+ /// [Snowflake]: https://docs.snowflake.com/en/sql-reference/snowflake-scripting/declare
1535+ /// [BigQuery]: https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#declare
1536+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1537+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1538+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1539+ pub struct Declare {
1540+ /// The name(s) being declared.
1541+ /// Example: `DECLARE a, b, c DEFAULT 42;
1542+ pub names : Vec < Ident > ,
1543+ /// Data-type assigned to the declared variable.
1544+ /// Example: `DECLARE x INT64 DEFAULT 42;
1545+ pub data_type : Option < DataType > ,
1546+ /// Expression being assigned to the declared variable.
1547+ pub assignment : Option < DeclareAssignment > ,
1548+ /// Represents the type of the declared variable.
1549+ pub declare_type : Option < DeclareType > ,
1550+ /// Causes the cursor to return data in binary rather than in text format.
1551+ pub binary : Option < bool > ,
1552+ /// None = Not specified
1553+ /// Some(true) = INSENSITIVE
1554+ /// Some(false) = ASENSITIVE
1555+ pub sensitive : Option < bool > ,
1556+ /// None = Not specified
1557+ /// Some(true) = SCROLL
1558+ /// Some(false) = NO SCROLL
1559+ pub scroll : Option < bool > ,
1560+ /// None = Not specified
1561+ /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits
1562+ /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it
1563+ pub hold : Option < bool > ,
1564+ /// `FOR <query>` clause in a CURSOR declaration.
1565+ pub for_query : Option < Box < Query > > ,
1566+ }
1567+
1568+ impl fmt:: Display for Declare {
1569+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1570+ let Declare {
1571+ names,
1572+ data_type,
1573+ assignment,
1574+ declare_type,
1575+ binary,
1576+ sensitive,
1577+ scroll,
1578+ hold,
1579+ for_query,
1580+ } = self ;
1581+ write ! ( f, "{}" , display_comma_separated( names) ) ?;
1582+
1583+ if let Some ( true ) = binary {
1584+ write ! ( f, " BINARY" ) ?;
1585+ }
1586+
1587+ if let Some ( sensitive) = sensitive {
1588+ if * sensitive {
1589+ write ! ( f, " INSENSITIVE" ) ?;
1590+ } else {
1591+ write ! ( f, " ASENSITIVE" ) ?;
1592+ }
1593+ }
1594+
1595+ if let Some ( scroll) = scroll {
1596+ if * scroll {
1597+ write ! ( f, " SCROLL" ) ?;
1598+ } else {
1599+ write ! ( f, " NO SCROLL" ) ?;
1600+ }
1601+ }
1602+
1603+ if let Some ( declare_type) = declare_type {
1604+ write ! ( f, " {declare_type}" ) ?;
1605+ }
1606+
1607+ if let Some ( hold) = hold {
1608+ if * hold {
1609+ write ! ( f, " WITH HOLD" ) ?;
1610+ } else {
1611+ write ! ( f, " WITHOUT HOLD" ) ?;
1612+ }
1613+ }
1614+
1615+ if let Some ( query) = for_query {
1616+ write ! ( f, " FOR {query}" ) ?;
1617+ }
1618+
1619+ if let Some ( data_type) = data_type {
1620+ write ! ( f, " {data_type}" ) ?;
1621+ }
1622+
1623+ if let Some ( expr) = assignment {
1624+ write ! ( f, " {expr}" ) ?;
1625+ }
1626+ Ok ( ( ) )
1627+ }
1628+ }
1629+
14251630/// Sql options of a `CREATE TABLE` statement.
14261631#[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
14271632#[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
@@ -1873,25 +2078,7 @@ pub enum Statement {
18732078 ///
18742079 /// Note: this is a PostgreSQL-specific statement,
18752080 /// but may also compatible with other SQL.
1876- Declare {
1877- /// Cursor name
1878- name : Ident ,
1879- /// Causes the cursor to return data in binary rather than in text format.
1880- binary : bool ,
1881- /// None = Not specified
1882- /// Some(true) = INSENSITIVE
1883- /// Some(false) = ASENSITIVE
1884- sensitive : Option < bool > ,
1885- /// None = Not specified
1886- /// Some(true) = SCROLL
1887- /// Some(false) = NO SCROLL
1888- scroll : Option < bool > ,
1889- /// None = Not specified
1890- /// Some(true) = WITH HOLD, specifies that the cursor can continue to be used after the transaction that created it successfully commits
1891- /// Some(false) = WITHOUT HOLD, specifies that the cursor cannot be used outside of the transaction that created it
1892- hold : Option < bool > ,
1893- query : Box < Query > ,
1894- } ,
2081+ Declare { stmts : Vec < Declare > } ,
18952082 /// ```sql
18962083 /// CREATE EXTENSION [ IF NOT EXISTS ] extension_name
18972084 /// [ WITH ] [ SCHEMA schema_name ]
@@ -2447,47 +2634,9 @@ impl fmt::Display for Statement {
24472634 write ! ( f, "{statement}" )
24482635 }
24492636 Statement :: Query ( s) => write ! ( f, "{s}" ) ,
2450- Statement :: Declare {
2451- name,
2452- binary,
2453- sensitive,
2454- scroll,
2455- hold,
2456- query,
2457- } => {
2458- write ! ( f, "DECLARE {name} " ) ?;
2459-
2460- if * binary {
2461- write ! ( f, "BINARY " ) ?;
2462- }
2463-
2464- if let Some ( sensitive) = sensitive {
2465- if * sensitive {
2466- write ! ( f, "INSENSITIVE " ) ?;
2467- } else {
2468- write ! ( f, "ASENSITIVE " ) ?;
2469- }
2470- }
2471-
2472- if let Some ( scroll) = scroll {
2473- if * scroll {
2474- write ! ( f, "SCROLL " ) ?;
2475- } else {
2476- write ! ( f, "NO SCROLL " ) ?;
2477- }
2478- }
2479-
2480- write ! ( f, "CURSOR " ) ?;
2481-
2482- if let Some ( hold) = hold {
2483- if * hold {
2484- write ! ( f, "WITH HOLD " ) ?;
2485- } else {
2486- write ! ( f, "WITHOUT HOLD " ) ?;
2487- }
2488- }
2489-
2490- write ! ( f, "FOR {query}" )
2637+ Statement :: Declare { stmts } => {
2638+ write ! ( f, "DECLARE " ) ?;
2639+ write ! ( f, "{}" , display_separated( stmts, "; " ) )
24912640 }
24922641 Statement :: Fetch {
24932642 name,
0 commit comments