@@ -920,6 +920,12 @@ pub(crate) fn table_json(t: &Table) -> Value {
920920 "CreateTime" : t. create_time. timestamp( ) as f64 ,
921921 "UpdateTime" : t. update_time. timestamp( ) as f64 ,
922922 } ) ;
923+ // Emit CatalogId only when populated: AWS omits absent members rather than
924+ // returning an empty string, and tables restored from a pre-`catalog_id`
925+ // snapshot carry an empty default.
926+ if !t. catalog_id . is_empty ( ) {
927+ o[ "CatalogId" ] = json ! ( t. catalog_id) ;
928+ }
923929 if let Some ( ref d) = t. description {
924930 o[ "Description" ] = json ! ( d) ;
925931 }
@@ -944,6 +950,15 @@ pub(crate) fn table_json(t: &Table) -> Value {
944950 o
945951}
946952
953+ /// The current (latest) archived VersionId for a table, defaulting to "1" for
954+ /// tables predating the version archive. Glue reports this on GetTable(s).
955+ fn current_table_version ( st : & crate :: state:: GlueState , db : & str , table : & str ) -> String {
956+ st. table_version_ids ( db, table)
957+ . last ( )
958+ . map ( |n| n. to_string ( ) )
959+ . unwrap_or_else ( || "1" . to_string ( ) )
960+ }
961+
947962pub ( crate ) fn partition_json ( p : & Partition ) -> Value {
948963 let mut o = json ! ( {
949964 "Values" : p. values,
@@ -1038,13 +1053,19 @@ impl GlueService {
10381053 }
10391054
10401055 pub ( crate ) fn get_databases ( & self , req : & AwsRequest ) -> Result < AwsResponse , AwsServiceError > {
1056+ let body = req. json_body ( ) ;
10411057 let accounts = self . state . read ( ) ;
10421058 let dbs: Vec < Value > = accounts
10431059 . get ( & req. account_id )
10441060 . and_then ( |s| s. dbs_in ( & req. region ) )
10451061 . map ( |map| map. values ( ) . map ( database_json) . collect ( ) )
10461062 . unwrap_or_default ( ) ;
1047- Ok ( AwsResponse :: ok_json ( json ! ( { "DatabaseList" : dbs} ) ) )
1063+ let ( page, token) = crate :: common:: paginate_body ( & body, dbs) ;
1064+ let mut resp = json ! ( { "DatabaseList" : page } ) ;
1065+ if let Some ( t) = token {
1066+ resp[ "NextToken" ] = json ! ( t) ;
1067+ }
1068+ Ok ( AwsResponse :: ok_json ( resp) )
10481069 }
10491070
10501071 pub ( crate ) fn update_database ( & self , req : & AwsRequest ) -> Result < AwsResponse , AwsServiceError > {
@@ -1104,6 +1125,7 @@ impl GlueService {
11041125 let table = Table {
11051126 name : name. clone ( ) ,
11061127 database_name : db_name. clone ( ) ,
1128+ catalog_id : req. account_id . clone ( ) ,
11071129 description : input[ "Description" ] . as_str ( ) . map ( |s| s. to_string ( ) ) ,
11081130 owner : input[ "Owner" ] . as_str ( ) . map ( |s| s. to_string ( ) ) ,
11091131 create_time : now,
@@ -1145,7 +1167,9 @@ impl GlueService {
11451167 . tables
11461168 . get ( name)
11471169 . ok_or_else ( || entity_not_found ( format ! ( "Table {name} not found" ) ) ) ?;
1148- Ok ( AwsResponse :: ok_json ( json ! ( { "Table" : table_json( t) } ) ) )
1170+ let mut tj = table_json ( t) ;
1171+ tj[ "VersionId" ] = json ! ( current_table_version( state, db_name, name) ) ;
1172+ Ok ( AwsResponse :: ok_json ( json ! ( { "Table" : tj} ) ) )
11491173 }
11501174
11511175 pub ( crate ) fn get_tables ( & self , req : & AwsRequest ) -> Result < AwsResponse , AwsServiceError > {
@@ -1161,19 +1185,24 @@ impl GlueService {
11611185 . filter ( |e| !e. is_empty ( ) )
11621186 . and_then ( |e| regex:: Regex :: new ( e) . ok ( ) ) ;
11631187 let accounts = self . state . read ( ) ;
1164- let tables: Vec < Value > = accounts
1165- . get ( & req. account_id )
1166- . and_then ( |s| s. dbs_in ( & req. region ) )
1167- . and_then ( |dbs| dbs. get ( db_name) )
1168- . map ( |db| {
1169- db. tables
1170- . values ( )
1171- . filter ( |t| name_filter. as_ref ( ) . is_none_or ( |re| re. is_match ( & t. name ) ) )
1172- . map ( table_json)
1173- . collect ( )
1174- } )
1175- . unwrap_or_default ( ) ;
1176- Ok ( AwsResponse :: ok_json ( json ! ( { "TableList" : tables} ) ) )
1188+ let mut tables: Vec < Value > = Vec :: new ( ) ;
1189+ if let Some ( s) = accounts. get ( & req. account_id ) {
1190+ if let Some ( db) = s. dbs_in ( & req. region ) . and_then ( |dbs| dbs. get ( db_name) ) {
1191+ for t in db. tables . values ( ) {
1192+ if name_filter. as_ref ( ) . is_none_or ( |re| re. is_match ( & t. name ) ) {
1193+ let mut tj = table_json ( t) ;
1194+ tj[ "VersionId" ] = json ! ( current_table_version( s, db_name, & t. name) ) ;
1195+ tables. push ( tj) ;
1196+ }
1197+ }
1198+ }
1199+ }
1200+ let ( page, token) = crate :: common:: paginate_body ( & body, tables) ;
1201+ let mut resp = json ! ( { "TableList" : page } ) ;
1202+ if let Some ( t) = token {
1203+ resp[ "NextToken" ] = json ! ( t) ;
1204+ }
1205+ Ok ( AwsResponse :: ok_json ( resp) )
11771206 }
11781207
11791208 pub ( crate ) fn update_table ( & self , req : & AwsRequest ) -> Result < AwsResponse , AwsServiceError > {
@@ -1341,6 +1370,19 @@ impl GlueService {
13411370 . as_str ( )
13421371 . ok_or_else ( || missing ( "TableName" ) ) ?;
13431372 let expression = body[ "Expression" ] . as_str ( ) . unwrap_or ( "" ) ;
1373+ // Parallel-scan support: when a `Segment{SegmentNumber, TotalSegments}`
1374+ // is supplied, each worker must see a disjoint slice of the matching
1375+ // partitions so the union across all segments equals the full set with
1376+ // no duplicates. Partition the deterministic (BTreeMap-ordered) match
1377+ // list by index modulo TotalSegments.
1378+ let segment = & body[ "Segment" ] ;
1379+ let ( segment_number, total_segments) = if segment. is_object ( ) {
1380+ let total = segment[ "TotalSegments" ] . as_u64 ( ) . unwrap_or ( 1 ) . max ( 1 ) ;
1381+ let number = segment[ "SegmentNumber" ] . as_u64 ( ) . unwrap_or ( 0 ) ;
1382+ ( number, total)
1383+ } else {
1384+ ( 0 , 1 )
1385+ } ;
13441386 let accounts = self . state . read ( ) ;
13451387 let parts: Vec < Value > = accounts
13461388 . get ( & req. account_id )
@@ -1358,11 +1400,20 @@ impl GlueService {
13581400 & p. values ,
13591401 )
13601402 } )
1361- . map ( partition_json)
1403+ . enumerate ( )
1404+ . filter ( |( i, _) | {
1405+ total_segments == 1 || ( * i as u64 ) % total_segments == segment_number
1406+ } )
1407+ . map ( |( _, p) | partition_json ( p) )
13621408 . collect ( )
13631409 } )
13641410 . unwrap_or_default ( ) ;
1365- Ok ( AwsResponse :: ok_json ( json ! ( { "Partitions" : parts} ) ) )
1411+ let ( page, token) = crate :: common:: paginate_body ( & body, parts) ;
1412+ let mut resp = json ! ( { "Partitions" : page } ) ;
1413+ if let Some ( t) = token {
1414+ resp[ "NextToken" ] = json ! ( t) ;
1415+ }
1416+ Ok ( AwsResponse :: ok_json ( resp) )
13661417 }
13671418
13681419 pub ( crate ) fn update_partition (
0 commit comments