@@ -30,7 +30,8 @@ use uuid::Uuid;
3030
3131use crate :: spec:: {
3232 FormatVersion , Schema , SchemaId , Snapshot , SnapshotReference , SortOrder , TableMetadata ,
33- TableMetadataBuilder , UnboundPartitionSpec , ViewRepresentations ,
33+ TableMetadataBuilder , UnboundPartitionSpec , ViewFormatVersion , ViewRepresentations ,
34+ ViewVersion ,
3435} ;
3536use crate :: table:: Table ;
3637use crate :: { Error , ErrorKind , Result } ;
@@ -671,6 +672,64 @@ pub struct ViewCreation {
671672 pub summary : HashMap < String , String > ,
672673}
673674
675+ /// ViewUpdate represents an update to a view in the catalog.
676+ #[ derive( Clone , Debug , PartialEq , Serialize , Deserialize ) ]
677+ #[ serde( tag = "action" , rename_all = "kebab-case" ) ]
678+ pub enum ViewUpdate {
679+ /// Assign a new UUID to the view
680+ #[ serde( rename_all = "kebab-case" ) ]
681+ AssignUuid {
682+ /// The new UUID to assign.
683+ uuid : uuid:: Uuid ,
684+ } ,
685+ /// Upgrade view's format version
686+ #[ serde( rename_all = "kebab-case" ) ]
687+ UpgradeFormatVersion {
688+ /// Target format upgrade to.
689+ format_version : ViewFormatVersion ,
690+ } ,
691+ /// Add a new schema to the view
692+ #[ serde( rename_all = "kebab-case" ) ]
693+ AddSchema {
694+ /// The schema to add.
695+ schema : Schema ,
696+ /// The last column id of the view.
697+ last_column_id : Option < i32 > ,
698+ } ,
699+ /// Set view's current schema
700+ #[ serde( rename_all = "kebab-case" ) ]
701+ SetLocation {
702+ /// New location for view.
703+ location : String ,
704+ } ,
705+ /// Set view's properties
706+ ///
707+ /// Matching keys are updated, and non-matching keys are left unchanged.
708+ #[ serde( rename_all = "kebab-case" ) ]
709+ SetProperties {
710+ /// Properties to update for view.
711+ updates : HashMap < String , String > ,
712+ } ,
713+ /// Remove view's properties
714+ #[ serde( rename_all = "kebab-case" ) ]
715+ RemoveProperties {
716+ /// Properties to remove
717+ removals : Vec < String > ,
718+ } ,
719+ /// Add a new version to the view
720+ #[ serde( rename_all = "kebab-case" ) ]
721+ AddViewVersion {
722+ /// The view version to add.
723+ view_version : ViewVersion ,
724+ } ,
725+ /// Set view's current version
726+ #[ serde( rename_all = "kebab-case" ) ]
727+ SetCurrentViewVersion {
728+ /// View version id to set as current, or -1 to set last added version
729+ view_version_id : i32 ,
730+ } ,
731+ }
732+
674733#[ cfg( test) ]
675734mod tests {
676735 use std:: collections:: HashMap ;
@@ -680,10 +739,13 @@ mod tests {
680739 use serde:: Serialize ;
681740 use uuid:: uuid;
682741
742+ use super :: ViewUpdate ;
683743 use crate :: spec:: {
684744 FormatVersion , NestedField , NullOrder , Operation , PrimitiveType , Schema , Snapshot ,
685- SnapshotReference , SnapshotRetention , SortDirection , SortField , SortOrder , Summary ,
686- TableMetadata , TableMetadataBuilder , Transform , Type , UnboundPartitionSpec ,
745+ SnapshotReference , SnapshotRetention , SortDirection , SortField , SortOrder ,
746+ SqlViewRepresentation , Summary , TableMetadata , TableMetadataBuilder , Transform , Type ,
747+ UnboundPartitionSpec , ViewFormatVersion , ViewRepresentation , ViewRepresentations ,
748+ ViewVersion ,
687749 } ;
688750 use crate :: { NamespaceIdent , TableCreation , TableIdent , TableRequirement , TableUpdate } ;
689751
@@ -1528,4 +1590,200 @@ mod tests {
15281590 . unwrap ( ) ;
15291591 assert_eq ! ( updated_metadata. uuid( ) , uuid) ;
15301592 }
1593+
1594+ #[ test]
1595+ fn test_view_assign_uuid ( ) {
1596+ test_serde_json (
1597+ r#"
1598+ {
1599+ "action": "assign-uuid",
1600+ "uuid": "2cc52516-5e73-41f2-b139-545d41a4e151"
1601+ }
1602+ "# ,
1603+ ViewUpdate :: AssignUuid {
1604+ uuid : uuid ! ( "2cc52516-5e73-41f2-b139-545d41a4e151" ) ,
1605+ } ,
1606+ ) ;
1607+ }
1608+
1609+ #[ test]
1610+ fn test_view_upgrade_format_version ( ) {
1611+ test_serde_json (
1612+ r#"
1613+ {
1614+ "action": "upgrade-format-version",
1615+ "format-version": 1
1616+ }
1617+ "# ,
1618+ ViewUpdate :: UpgradeFormatVersion {
1619+ format_version : ViewFormatVersion :: V1 ,
1620+ } ,
1621+ ) ;
1622+ }
1623+
1624+ #[ test]
1625+ fn test_view_add_schema ( ) {
1626+ let test_schema = Schema :: builder ( )
1627+ . with_schema_id ( 1 )
1628+ . with_identifier_field_ids ( vec ! [ 2 ] )
1629+ . with_fields ( vec ! [
1630+ NestedField :: optional( 1 , "foo" , Type :: Primitive ( PrimitiveType :: String ) ) . into( ) ,
1631+ NestedField :: required( 2 , "bar" , Type :: Primitive ( PrimitiveType :: Int ) ) . into( ) ,
1632+ NestedField :: optional( 3 , "baz" , Type :: Primitive ( PrimitiveType :: Boolean ) ) . into( ) ,
1633+ ] )
1634+ . build ( )
1635+ . unwrap ( ) ;
1636+ test_serde_json (
1637+ r#"
1638+ {
1639+ "action": "add-schema",
1640+ "schema": {
1641+ "type": "struct",
1642+ "schema-id": 1,
1643+ "fields": [
1644+ {
1645+ "id": 1,
1646+ "name": "foo",
1647+ "required": false,
1648+ "type": "string"
1649+ },
1650+ {
1651+ "id": 2,
1652+ "name": "bar",
1653+ "required": true,
1654+ "type": "int"
1655+ },
1656+ {
1657+ "id": 3,
1658+ "name": "baz",
1659+ "required": false,
1660+ "type": "boolean"
1661+ }
1662+ ],
1663+ "identifier-field-ids": [
1664+ 2
1665+ ]
1666+ },
1667+ "last-column-id": 3
1668+ }
1669+ "# ,
1670+ ViewUpdate :: AddSchema {
1671+ schema : test_schema. clone ( ) ,
1672+ last_column_id : Some ( 3 ) ,
1673+ } ,
1674+ ) ;
1675+ }
1676+
1677+ #[ test]
1678+ fn test_view_set_location ( ) {
1679+ test_serde_json (
1680+ r#"
1681+ {
1682+ "action": "set-location",
1683+ "location": "s3://db/view"
1684+ }
1685+ "# ,
1686+ ViewUpdate :: SetLocation {
1687+ location : "s3://db/view" . to_string ( ) ,
1688+ } ,
1689+ ) ;
1690+ }
1691+
1692+ #[ test]
1693+ fn test_view_set_properties ( ) {
1694+ test_serde_json (
1695+ r#"
1696+ {
1697+ "action": "set-properties",
1698+ "updates": {
1699+ "prop1": "v1",
1700+ "prop2": "v2"
1701+ }
1702+ }
1703+ "# ,
1704+ ViewUpdate :: SetProperties {
1705+ updates : vec ! [
1706+ ( "prop1" . to_string( ) , "v1" . to_string( ) ) ,
1707+ ( "prop2" . to_string( ) , "v2" . to_string( ) ) ,
1708+ ]
1709+ . into_iter ( )
1710+ . collect ( ) ,
1711+ } ,
1712+ ) ;
1713+ }
1714+
1715+ #[ test]
1716+ fn test_view_remove_properties ( ) {
1717+ test_serde_json (
1718+ r#"
1719+ {
1720+ "action": "remove-properties",
1721+ "removals": [
1722+ "prop1",
1723+ "prop2"
1724+ ]
1725+ }
1726+ "# ,
1727+ ViewUpdate :: RemoveProperties {
1728+ removals : vec ! [ "prop1" . to_string( ) , "prop2" . to_string( ) ] ,
1729+ } ,
1730+ ) ;
1731+ }
1732+
1733+ #[ test]
1734+ fn test_view_add_view_version ( ) {
1735+ test_serde_json (
1736+ r#"
1737+ {
1738+ "action": "add-view-version",
1739+ "view-version": {
1740+ "version-id" : 1,
1741+ "timestamp-ms" : 1573518431292,
1742+ "schema-id" : 1,
1743+ "default-catalog" : "prod",
1744+ "default-namespace" : [ "default" ],
1745+ "summary" : {
1746+ "engine-name" : "Spark"
1747+ },
1748+ "representations" : [ {
1749+ "type" : "sql",
1750+ "sql" : "SELECT\n COUNT(1), CAST(event_ts AS DATE)\nFROM events\nGROUP BY 2",
1751+ "dialect" : "spark"
1752+ } ]
1753+ }
1754+ }
1755+ "# ,
1756+ ViewUpdate :: AddViewVersion {
1757+ view_version : ViewVersion :: builder ( )
1758+ . with_version_id ( 1 )
1759+ . with_timestamp_ms ( 1573518431292 )
1760+ . with_schema_id ( 1 )
1761+ . with_default_catalog ( Some ( "prod" . to_string ( ) ) )
1762+ . with_default_namespace ( NamespaceIdent :: from_strs ( vec ! [ "default" ] ) . unwrap ( ) )
1763+ . with_summary (
1764+ vec ! [ ( "engine-name" . to_string( ) , "Spark" . to_string( ) ) ]
1765+ . into_iter ( )
1766+ . collect ( ) ,
1767+ )
1768+ . with_representations ( ViewRepresentations ( vec ! [ ViewRepresentation :: Sql ( SqlViewRepresentation {
1769+ sql: "SELECT\n COUNT(1), CAST(event_ts AS DATE)\n FROM events\n GROUP BY 2" . to_string( ) ,
1770+ dialect: "spark" . to_string( ) ,
1771+ } ) ] ) )
1772+ . build ( ) ,
1773+ } ,
1774+ ) ;
1775+ }
1776+
1777+ #[ test]
1778+ fn test_view_set_current_view_version ( ) {
1779+ test_serde_json (
1780+ r#"
1781+ {
1782+ "action": "set-current-view-version",
1783+ "view-version-id": 1
1784+ }
1785+ "# ,
1786+ ViewUpdate :: SetCurrentViewVersion { view_version_id : 1 } ,
1787+ ) ;
1788+ }
15311789}
0 commit comments