26
26
import pyarrow as pa
27
27
import pyarrow .feather as pa_feather
28
28
29
- import bigframes .core .compile
30
29
import bigframes .core .expression as ex
31
30
import bigframes .core .guid
32
31
import bigframes .core .identifiers as ids
35
34
import bigframes .core .nodes as nodes
36
35
from bigframes .core .ordering import OrderingExpression
37
36
import bigframes .core .ordering as orderings
38
- import bigframes .core .rewrite
39
37
import bigframes .core .schema as schemata
40
38
import bigframes .core .tree_properties
41
39
import bigframes .core .utils
42
40
from bigframes .core .window_spec import WindowSpec
43
41
import bigframes .dtypes
44
42
import bigframes .operations as ops
45
43
import bigframes .operations .aggregations as agg_ops
46
- import bigframes .session ._io .bigquery
47
44
48
45
if typing .TYPE_CHECKING :
49
46
from bigframes .session import Session
@@ -199,6 +196,8 @@ def as_cached(
199
196
200
197
def _try_evaluate_local (self ):
201
198
"""Use only for unit testing paths - not fully featured. Will throw exception if fails."""
199
+ import bigframes .core .compile
200
+
202
201
return bigframes .core .compile .test_only_try_evaluate (self .node )
203
202
204
203
def get_column_type (self , key : str ) -> bigframes .dtypes .Dtype :
@@ -422,22 +421,7 @@ def relational_join(
422
421
l_mapping = { # Identity mapping, only rename right side
423
422
lcol .name : lcol .name for lcol in self .node .ids
424
423
}
425
- r_mapping = { # Rename conflicting names
426
- rcol .name : rcol .name
427
- if (rcol .name not in l_mapping )
428
- else bigframes .core .guid .generate_guid ()
429
- for rcol in other .node .ids
430
- }
431
- other_node = other .node
432
- if set (other_node .ids ) & set (self .node .ids ):
433
- other_node = nodes .SelectionNode (
434
- other_node ,
435
- tuple (
436
- (ex .deref (old_id ), ids .ColumnId (new_id ))
437
- for old_id , new_id in r_mapping .items ()
438
- ),
439
- )
440
-
424
+ other_node , r_mapping = self .prepare_join_names (other )
441
425
join_node = nodes .JoinNode (
442
426
left_child = self .node ,
443
427
right_child = other_node ,
@@ -449,14 +433,63 @@ def relational_join(
449
433
)
450
434
return ArrayValue (join_node ), (l_mapping , r_mapping )
451
435
452
- def try_align_as_projection (
436
+ def try_row_join (
437
+ self ,
438
+ other : ArrayValue ,
439
+ conditions : typing .Tuple [typing .Tuple [str , str ], ...] = (),
440
+ ) -> Optional [
441
+ typing .Tuple [ArrayValue , typing .Tuple [dict [str , str ], dict [str , str ]]]
442
+ ]:
443
+ l_mapping = { # Identity mapping, only rename right side
444
+ lcol .name : lcol .name for lcol in self .node .ids
445
+ }
446
+ other_node , r_mapping = self .prepare_join_names (other )
447
+ import bigframes .core .rewrite
448
+
449
+ result_node = bigframes .core .rewrite .try_join_as_projection (
450
+ self .node , other_node , conditions
451
+ )
452
+ if result_node is None :
453
+ return None
454
+
455
+ return (
456
+ ArrayValue (result_node ),
457
+ (l_mapping , r_mapping ),
458
+ )
459
+
460
+ def prepare_join_names (
461
+ self , other : ArrayValue
462
+ ) -> Tuple [bigframes .core .nodes .BigFrameNode , dict [str , str ]]:
463
+ if set (other .node .ids ) & set (self .node .ids ):
464
+ r_mapping = { # Rename conflicting names
465
+ rcol .name : rcol .name
466
+ if (rcol .name not in self .column_ids )
467
+ else bigframes .core .guid .generate_guid ()
468
+ for rcol in other .node .ids
469
+ }
470
+ return (
471
+ nodes .SelectionNode (
472
+ other .node ,
473
+ tuple (
474
+ (ex .deref (old_id ), ids .ColumnId (new_id ))
475
+ for old_id , new_id in r_mapping .items ()
476
+ ),
477
+ ),
478
+ r_mapping ,
479
+ )
480
+ else :
481
+ return other .node , {id : id for id in other .column_ids }
482
+
483
+ def try_legacy_row_join (
453
484
self ,
454
485
other : ArrayValue ,
455
486
join_type : join_def .JoinType ,
456
487
join_keys : typing .Tuple [join_def .CoalescedColumnMapping , ...],
457
488
mappings : typing .Tuple [join_def .JoinColumnMapping , ...],
458
489
) -> typing .Optional [ArrayValue ]:
459
- result = bigframes .core .rewrite .join_as_projection (
490
+ import bigframes .core .rewrite
491
+
492
+ result = bigframes .core .rewrite .legacy_join_as_projection (
460
493
self .node , other .node , join_keys , mappings , join_type
461
494
)
462
495
if result is not None :
@@ -488,11 +521,4 @@ def _gen_namespaced_uid(self) -> str:
488
521
return self ._gen_namespaced_uids (1 )[0 ]
489
522
490
523
def _gen_namespaced_uids (self , n : int ) -> List [str ]:
491
- i = len (self .node .defined_variables )
492
- genned_ids : List [str ] = []
493
- while len (genned_ids ) < n :
494
- attempted_id = f"col_{ i } "
495
- if attempted_id not in self .node .defined_variables :
496
- genned_ids .append (attempted_id )
497
- i = i + 1
498
- return genned_ids
524
+ return [ids .ColumnId .unique ().name for _ in range (n )]
0 commit comments