@@ -26,8 +26,8 @@ use crate::proto::request::ClientReq;
2626use crate :: proto:: response:: ClientResp ;
2727use crate :: proto:: {
2828 ColumnType , GetFeaturesReq , GetFeaturesResp , GetHostedTablesReq , GetHostedTablesResp ,
29- HostedTable , MakeTableReq , RemoveHostedTablesUpdateReq , Request , Response , ServerError ,
30- ServerSystemInfoReq ,
29+ HostedTable , MakeJoinTableReq , MakeTableReq , RemoveHostedTablesUpdateReq , Request , Response ,
30+ ServerError , ServerSystemInfoReq ,
3131} ;
3232use crate :: table:: { Table , TableInitOptions , TableOptions } ;
3333use crate :: table_data:: { TableData , UpdateData } ;
@@ -589,6 +589,45 @@ impl Client {
589589 }
590590 }
591591
592+ /// Create a new read-only [`Table`] by performing an INNER JOIN on two
593+ /// source tables. The resulting table is reactive: when either source
594+ /// table is updated, the join is automatically recomputed.
595+ ///
596+ /// # Arguments
597+ ///
598+ /// * `left` - The left source table.
599+ /// * `right` - The right source table.
600+ /// * `on` - The column name to join on. Must exist in both tables with the
601+ /// same type.
602+ /// * `name` - Optional name for the resulting table.
603+ pub async fn join (
604+ & self ,
605+ left : & Table ,
606+ right : & Table ,
607+ on : & str ,
608+ name : Option < String > ,
609+ ) -> ClientResult < Table > {
610+ let entity_id = name. unwrap_or_else ( randid) ;
611+ let msg = Request {
612+ msg_id : self . gen_id ( ) ,
613+ entity_id : entity_id. clone ( ) ,
614+ client_req : Some ( ClientReq :: MakeJoinTableReq ( MakeJoinTableReq {
615+ left_table_id : left. get_name ( ) . to_owned ( ) ,
616+ right_table_id : right. get_name ( ) . to_owned ( ) ,
617+ on_column : on. to_owned ( ) ,
618+ } ) ) ,
619+ } ;
620+
621+ let client = self . clone ( ) ;
622+ match self . oneshot ( & msg) . await ? {
623+ ClientResp :: MakeJoinTableResp ( _) => Ok ( Table :: new ( entity_id, client, TableOptions {
624+ index : Some ( on. to_owned ( ) ) ,
625+ limit : None ,
626+ } ) ) ,
627+ resp => Err ( resp. into ( ) ) ,
628+ }
629+ }
630+
592631 async fn get_table_infos ( & self ) -> ClientResult < Vec < HostedTable > > {
593632 let msg = Request {
594633 msg_id : self . gen_id ( ) ,
0 commit comments