Skip to content

Commit e37af77

Browse files
SNOW-2268207: Support lateral join (#3971)
1 parent 377001a commit e37af77

File tree

12 files changed

+1207
-245
lines changed

12 files changed

+1207
-245
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#### New Features
88

9+
- Added support for `DataFrame.lateral_join`
910
- Added support for `Session.client_telemetry`.
1011
- Added support for `Session.udf_profiler`.
1112
- Added support for `functions.ai_translate`.

docs/source/snowpark/dataframe.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ DataFrame
6161
DataFrame.intersect
6262
DataFrame.join
6363
DataFrame.join_table_function
64+
DataFrame.lateral_join
6465
DataFrame.limit
6566
DataFrame.minus
6667
DataFrame.natural_join

src/snowflake/snowpark/_internal/analyzer/analyzer_utils.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
LeftAnti,
2727
LeftSemi,
2828
NaturalJoin,
29+
LateralJoin,
2930
UsingJoin,
3031
)
3132
from snowflake.snowpark._internal.analyzer.datatype_mapper import (
@@ -169,6 +170,7 @@
169170
OUTER = " OUTER "
170171
RECURSIVE = " RECURSIVE "
171172
MODE = " MODE "
173+
INNER = " INNER "
172174
LATERAL = " LATERAL "
173175
PUT = " PUT "
174176
GET = " GET "
@@ -879,6 +881,65 @@ def asof_join_statement(
879881
)
880882

881883

884+
def lateral_join_statement(
885+
left: str,
886+
right: str,
887+
join_condition: str,
888+
use_constant_subquery_alias: bool,
889+
) -> str:
890+
left_alias = (
891+
"SNOWPARK_LEFT"
892+
if use_constant_subquery_alias
893+
else random_name_for_temp_object(TempObjectType.TABLE)
894+
)
895+
right_alias = (
896+
"SNOWPARK_RIGHT"
897+
if use_constant_subquery_alias
898+
else random_name_for_temp_object(TempObjectType.TABLE)
899+
)
900+
901+
# wrap the right side in subquery with WHERE clause if condition exists
902+
if join_condition:
903+
right_with_condition = (
904+
LEFT_PARENTHESIS
905+
+ NEW_LINE
906+
+ SELECT
907+
+ STAR
908+
+ FROM
909+
+ LEFT_PARENTHESIS
910+
+ right
911+
+ RIGHT_PARENTHESIS
912+
+ WHERE
913+
+ join_condition
914+
+ NEW_LINE
915+
+ RIGHT_PARENTHESIS
916+
)
917+
else:
918+
right_with_condition = LEFT_PARENTHESIS + right + RIGHT_PARENTHESIS
919+
920+
return (
921+
SELECT
922+
+ STAR
923+
+ NEW_LINE
924+
+ FROM
925+
+ LEFT_PARENTHESIS
926+
+ NEW_LINE
927+
+ left
928+
+ NEW_LINE
929+
+ RIGHT_PARENTHESIS
930+
+ AS
931+
+ left_alias
932+
+ NEW_LINE
933+
+ INNER
934+
+ JOIN
935+
+ LATERAL
936+
+ NEW_LINE
937+
+ right_with_condition
938+
+ AS
939+
+ right_alias
940+
)
941+
942+
882943
def snowflake_supported_join_statement(
883944
left: str,
884945
right: str,
@@ -983,6 +1044,10 @@ def join_statement(
9831044
return asof_join_statement(
9841045
left, right, join_condition, match_condition, use_constant_subquery_alias
9851046
)
1047+
if isinstance(join_type, LateralJoin):
1048+
return lateral_join_statement(
1049+
left, right, join_condition, use_constant_subquery_alias
1050+
)
9861051
if isinstance(join_type, UsingJoin) and isinstance(
9871052
join_type.tpe, (LeftSemi, LeftAnti)
9881053
):

src/snowflake/snowpark/_internal/analyzer/binary_plan_node.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ class AsOf(JoinType):
137137
sql = "ASOF"
138138

139139

140+
class LateralJoin(JoinType):
141+
sql = "INNER JOIN LATERAL"
142+
143+
140144
class NaturalJoin(JoinType):
141145
def __init__(self, tpe: JoinType) -> None:
142146
if not isinstance(

0 commit comments

Comments
 (0)