@@ -726,6 +726,33 @@ pub enum TableFactor {
726726 with_offset : bool ,
727727 with_offset_alias : Option < Ident > ,
728728 } ,
729+ /// The `JSON_TABLE` table-valued function.
730+ /// Part of the SQL standard, but implemented only by MySQL, Oracle, and DB2.
731+ ///
732+ /// https://modern-sql.com/blog/2017-06/whats-new-in-sql-2016#json_table
733+ /// https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html#function_json-table
734+ ///
735+ /// ```sql
736+ /// SELECT * FROM JSON_TABLE(
737+ /// '[{"a": 1, "b": 2}, {"a": 3, "b": 4}]',
738+ /// '$[*]' COLUMNS(
739+ /// a INT PATH '$.a' DEFAULT '0' ON EMPTY,
740+ /// b INT PATH '$.b' NULL ON ERROR
741+ /// )
742+ /// ) AS jt;
743+ /// ````
744+ JsonTable {
745+ /// The JSON expression to be evaluated. It must evaluate to a json string
746+ json_expr : Expr ,
747+ /// The path to the array or object to be iterated over.
748+ /// It must evaluate to a json array or object.
749+ json_path : Value ,
750+ /// The columns to be extracted from each element of the array or object.
751+ /// Each column must have a name and a type.
752+ columns : Vec < JsonTableColumn > ,
753+ /// The alias for the table.
754+ alias : Option < TableAlias > ,
755+ } ,
729756 /// Represents a parenthesized table factor. The SQL spec only allows a
730757 /// join expression (`(foo <JOIN> bar [ <JOIN> baz ... ])`) to be nested,
731758 /// possibly several times.
@@ -848,6 +875,22 @@ impl fmt::Display for TableFactor {
848875 }
849876 Ok ( ( ) )
850877 }
878+ TableFactor :: JsonTable {
879+ json_expr,
880+ json_path,
881+ columns,
882+ alias,
883+ } => {
884+ write ! (
885+ f,
886+ "JSON_TABLE({json_expr}, {json_path} COLUMNS({columns}))" ,
887+ columns = display_comma_separated( columns)
888+ ) ?;
889+ if let Some ( alias) = alias {
890+ write ! ( f, " AS {alias}" ) ?;
891+ }
892+ Ok ( ( ) )
893+ }
851894 TableFactor :: NestedJoin {
852895 table_with_joins,
853896 alias,
@@ -1443,3 +1486,74 @@ impl fmt::Display for ForJson {
14431486 }
14441487 }
14451488}
1489+
1490+ /// A single column definition in MySQL's `JSON_TABLE` table valued function.
1491+ /// ```sql
1492+ /// SELECT *
1493+ /// FROM JSON_TABLE(
1494+ /// '["a", "b"]',
1495+ /// '$[*]' COLUMNS (
1496+ /// value VARCHAR(20) PATH '$'
1497+ /// )
1498+ /// ) AS jt;
1499+ /// ```
1500+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1501+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1502+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1503+ pub struct JsonTableColumn {
1504+ /// The name of the column to be extracted.
1505+ pub name : Ident ,
1506+ /// The type of the column to be extracted.
1507+ pub r#type : DataType ,
1508+ /// The path to the column to be extracted. Must be a literal string.
1509+ pub path : Value ,
1510+ /// true if the column is a boolean set to true if the given path exists
1511+ pub exists : bool ,
1512+ /// The empty handling clause of the column
1513+ pub on_empty : Option < JsonTableColumnErrorHandling > ,
1514+ /// The error handling clause of the column
1515+ pub on_error : Option < JsonTableColumnErrorHandling > ,
1516+ }
1517+
1518+ impl fmt:: Display for JsonTableColumn {
1519+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1520+ write ! (
1521+ f,
1522+ "{} {}{} PATH {}" ,
1523+ self . name,
1524+ self . r#type,
1525+ if self . exists { " EXISTS" } else { "" } ,
1526+ self . path
1527+ ) ?;
1528+ if let Some ( on_empty) = & self . on_empty {
1529+ write ! ( f, " {} ON EMPTY" , on_empty) ?;
1530+ }
1531+ if let Some ( on_error) = & self . on_error {
1532+ write ! ( f, " {} ON ERROR" , on_error) ?;
1533+ }
1534+ Ok ( ( ) )
1535+ }
1536+ }
1537+
1538+ /// Stores the error handling clause of a `JSON_TABLE` table valued function:
1539+ /// {NULL | DEFAULT json_string | ERROR} ON {ERROR | EMPTY }
1540+ #[ derive( Debug , Clone , PartialEq , PartialOrd , Eq , Ord , Hash ) ]
1541+ #[ cfg_attr( feature = "visitor" , derive( Visit , VisitMut ) ) ]
1542+ #[ cfg_attr( feature = "serde" , derive( Serialize , Deserialize ) ) ]
1543+ pub enum JsonTableColumnErrorHandling {
1544+ Null ,
1545+ Default ( Value ) ,
1546+ Error ,
1547+ }
1548+
1549+ impl fmt:: Display for JsonTableColumnErrorHandling {
1550+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1551+ match self {
1552+ JsonTableColumnErrorHandling :: Null => write ! ( f, "NULL" ) ,
1553+ JsonTableColumnErrorHandling :: Default ( json_string) => {
1554+ write ! ( f, "DEFAULT {}" , json_string)
1555+ }
1556+ JsonTableColumnErrorHandling :: Error => write ! ( f, "ERROR" ) ,
1557+ }
1558+ }
1559+ }
0 commit comments