sqlspec 0.16.1__cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (148) hide show
  1. 51ff5a9eadfdefd49f98__mypyc.cpython-39-aarch64-linux-gnu.so +0 -0
  2. sqlspec/__init__.py +92 -0
  3. sqlspec/__main__.py +12 -0
  4. sqlspec/__metadata__.py +14 -0
  5. sqlspec/_serialization.py +77 -0
  6. sqlspec/_sql.py +1780 -0
  7. sqlspec/_typing.py +680 -0
  8. sqlspec/adapters/__init__.py +0 -0
  9. sqlspec/adapters/adbc/__init__.py +5 -0
  10. sqlspec/adapters/adbc/_types.py +12 -0
  11. sqlspec/adapters/adbc/config.py +361 -0
  12. sqlspec/adapters/adbc/driver.py +512 -0
  13. sqlspec/adapters/aiosqlite/__init__.py +19 -0
  14. sqlspec/adapters/aiosqlite/_types.py +13 -0
  15. sqlspec/adapters/aiosqlite/config.py +253 -0
  16. sqlspec/adapters/aiosqlite/driver.py +248 -0
  17. sqlspec/adapters/asyncmy/__init__.py +19 -0
  18. sqlspec/adapters/asyncmy/_types.py +12 -0
  19. sqlspec/adapters/asyncmy/config.py +180 -0
  20. sqlspec/adapters/asyncmy/driver.py +274 -0
  21. sqlspec/adapters/asyncpg/__init__.py +21 -0
  22. sqlspec/adapters/asyncpg/_types.py +17 -0
  23. sqlspec/adapters/asyncpg/config.py +229 -0
  24. sqlspec/adapters/asyncpg/driver.py +344 -0
  25. sqlspec/adapters/bigquery/__init__.py +18 -0
  26. sqlspec/adapters/bigquery/_types.py +12 -0
  27. sqlspec/adapters/bigquery/config.py +298 -0
  28. sqlspec/adapters/bigquery/driver.py +558 -0
  29. sqlspec/adapters/duckdb/__init__.py +22 -0
  30. sqlspec/adapters/duckdb/_types.py +12 -0
  31. sqlspec/adapters/duckdb/config.py +504 -0
  32. sqlspec/adapters/duckdb/driver.py +368 -0
  33. sqlspec/adapters/oracledb/__init__.py +32 -0
  34. sqlspec/adapters/oracledb/_types.py +14 -0
  35. sqlspec/adapters/oracledb/config.py +317 -0
  36. sqlspec/adapters/oracledb/driver.py +538 -0
  37. sqlspec/adapters/psqlpy/__init__.py +16 -0
  38. sqlspec/adapters/psqlpy/_types.py +11 -0
  39. sqlspec/adapters/psqlpy/config.py +214 -0
  40. sqlspec/adapters/psqlpy/driver.py +530 -0
  41. sqlspec/adapters/psycopg/__init__.py +32 -0
  42. sqlspec/adapters/psycopg/_types.py +17 -0
  43. sqlspec/adapters/psycopg/config.py +426 -0
  44. sqlspec/adapters/psycopg/driver.py +796 -0
  45. sqlspec/adapters/sqlite/__init__.py +15 -0
  46. sqlspec/adapters/sqlite/_types.py +11 -0
  47. sqlspec/adapters/sqlite/config.py +240 -0
  48. sqlspec/adapters/sqlite/driver.py +294 -0
  49. sqlspec/base.py +571 -0
  50. sqlspec/builder/__init__.py +62 -0
  51. sqlspec/builder/_base.py +473 -0
  52. sqlspec/builder/_column.py +320 -0
  53. sqlspec/builder/_ddl.py +1346 -0
  54. sqlspec/builder/_ddl_utils.py +103 -0
  55. sqlspec/builder/_delete.py +76 -0
  56. sqlspec/builder/_insert.py +256 -0
  57. sqlspec/builder/_merge.py +71 -0
  58. sqlspec/builder/_parsing_utils.py +140 -0
  59. sqlspec/builder/_select.py +170 -0
  60. sqlspec/builder/_update.py +188 -0
  61. sqlspec/builder/mixins/__init__.py +55 -0
  62. sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
  63. sqlspec/builder/mixins/_delete_operations.py +41 -0
  64. sqlspec/builder/mixins/_insert_operations.py +244 -0
  65. sqlspec/builder/mixins/_join_operations.py +122 -0
  66. sqlspec/builder/mixins/_merge_operations.py +476 -0
  67. sqlspec/builder/mixins/_order_limit_operations.py +135 -0
  68. sqlspec/builder/mixins/_pivot_operations.py +153 -0
  69. sqlspec/builder/mixins/_select_operations.py +603 -0
  70. sqlspec/builder/mixins/_update_operations.py +187 -0
  71. sqlspec/builder/mixins/_where_clause.py +621 -0
  72. sqlspec/cli.py +247 -0
  73. sqlspec/config.py +395 -0
  74. sqlspec/core/__init__.py +63 -0
  75. sqlspec/core/cache.cpython-39-aarch64-linux-gnu.so +0 -0
  76. sqlspec/core/cache.py +871 -0
  77. sqlspec/core/compiler.cpython-39-aarch64-linux-gnu.so +0 -0
  78. sqlspec/core/compiler.py +417 -0
  79. sqlspec/core/filters.cpython-39-aarch64-linux-gnu.so +0 -0
  80. sqlspec/core/filters.py +830 -0
  81. sqlspec/core/hashing.cpython-39-aarch64-linux-gnu.so +0 -0
  82. sqlspec/core/hashing.py +310 -0
  83. sqlspec/core/parameters.cpython-39-aarch64-linux-gnu.so +0 -0
  84. sqlspec/core/parameters.py +1237 -0
  85. sqlspec/core/result.cpython-39-aarch64-linux-gnu.so +0 -0
  86. sqlspec/core/result.py +677 -0
  87. sqlspec/core/splitter.cpython-39-aarch64-linux-gnu.so +0 -0
  88. sqlspec/core/splitter.py +819 -0
  89. sqlspec/core/statement.cpython-39-aarch64-linux-gnu.so +0 -0
  90. sqlspec/core/statement.py +676 -0
  91. sqlspec/driver/__init__.py +19 -0
  92. sqlspec/driver/_async.py +502 -0
  93. sqlspec/driver/_common.py +631 -0
  94. sqlspec/driver/_sync.py +503 -0
  95. sqlspec/driver/mixins/__init__.py +6 -0
  96. sqlspec/driver/mixins/_result_tools.py +193 -0
  97. sqlspec/driver/mixins/_sql_translator.py +86 -0
  98. sqlspec/exceptions.py +193 -0
  99. sqlspec/extensions/__init__.py +0 -0
  100. sqlspec/extensions/aiosql/__init__.py +10 -0
  101. sqlspec/extensions/aiosql/adapter.py +461 -0
  102. sqlspec/extensions/litestar/__init__.py +6 -0
  103. sqlspec/extensions/litestar/_utils.py +52 -0
  104. sqlspec/extensions/litestar/cli.py +48 -0
  105. sqlspec/extensions/litestar/config.py +92 -0
  106. sqlspec/extensions/litestar/handlers.py +260 -0
  107. sqlspec/extensions/litestar/plugin.py +145 -0
  108. sqlspec/extensions/litestar/providers.py +454 -0
  109. sqlspec/loader.cpython-39-aarch64-linux-gnu.so +0 -0
  110. sqlspec/loader.py +760 -0
  111. sqlspec/migrations/__init__.py +35 -0
  112. sqlspec/migrations/base.py +414 -0
  113. sqlspec/migrations/commands.py +443 -0
  114. sqlspec/migrations/loaders.py +402 -0
  115. sqlspec/migrations/runner.py +213 -0
  116. sqlspec/migrations/tracker.py +140 -0
  117. sqlspec/migrations/utils.py +129 -0
  118. sqlspec/protocols.py +407 -0
  119. sqlspec/py.typed +0 -0
  120. sqlspec/storage/__init__.py +23 -0
  121. sqlspec/storage/backends/__init__.py +0 -0
  122. sqlspec/storage/backends/base.py +163 -0
  123. sqlspec/storage/backends/fsspec.py +386 -0
  124. sqlspec/storage/backends/obstore.py +459 -0
  125. sqlspec/storage/capabilities.py +102 -0
  126. sqlspec/storage/registry.py +239 -0
  127. sqlspec/typing.py +299 -0
  128. sqlspec/utils/__init__.py +3 -0
  129. sqlspec/utils/correlation.py +150 -0
  130. sqlspec/utils/deprecation.py +106 -0
  131. sqlspec/utils/fixtures.cpython-39-aarch64-linux-gnu.so +0 -0
  132. sqlspec/utils/fixtures.py +58 -0
  133. sqlspec/utils/logging.py +127 -0
  134. sqlspec/utils/module_loader.py +89 -0
  135. sqlspec/utils/serializers.py +4 -0
  136. sqlspec/utils/singleton.py +32 -0
  137. sqlspec/utils/sync_tools.cpython-39-aarch64-linux-gnu.so +0 -0
  138. sqlspec/utils/sync_tools.py +237 -0
  139. sqlspec/utils/text.cpython-39-aarch64-linux-gnu.so +0 -0
  140. sqlspec/utils/text.py +96 -0
  141. sqlspec/utils/type_guards.cpython-39-aarch64-linux-gnu.so +0 -0
  142. sqlspec/utils/type_guards.py +1139 -0
  143. sqlspec-0.16.1.dist-info/METADATA +365 -0
  144. sqlspec-0.16.1.dist-info/RECORD +148 -0
  145. sqlspec-0.16.1.dist-info/WHEEL +7 -0
  146. sqlspec-0.16.1.dist-info/entry_points.txt +2 -0
  147. sqlspec-0.16.1.dist-info/licenses/LICENSE +21 -0
  148. sqlspec-0.16.1.dist-info/licenses/NOTICE +29 -0
@@ -0,0 +1,244 @@
1
+ """Insert operation mixins for SQL builders."""
2
+
3
+ from collections.abc import Sequence
4
+ from typing import Any, Optional, TypeVar, Union
5
+
6
+ from mypy_extensions import trait
7
+ from sqlglot import exp
8
+ from typing_extensions import Self
9
+
10
+ from sqlspec.exceptions import SQLBuilderError
11
+ from sqlspec.protocols import SQLBuilderProtocol
12
+
13
+ BuilderT = TypeVar("BuilderT", bound=SQLBuilderProtocol)
14
+
15
+ __all__ = ("InsertFromSelectMixin", "InsertIntoClauseMixin", "InsertValuesMixin")
16
+
17
+
18
+ @trait
19
+ class InsertIntoClauseMixin:
20
+ """Mixin providing INTO clause for INSERT builders."""
21
+
22
+ __slots__ = ()
23
+
24
+ # Type annotation for PyRight - this will be provided by the base class
25
+ _expression: Optional[exp.Expression]
26
+
27
+ def into(self, table: str) -> Self:
28
+ """Set the target table for the INSERT statement.
29
+
30
+ Args:
31
+ table: The name of the table to insert data into.
32
+
33
+ Raises:
34
+ SQLBuilderError: If the current expression is not an INSERT statement.
35
+
36
+ Returns:
37
+ The current builder instance for method chaining.
38
+ """
39
+ if self._expression is None:
40
+ self._expression = exp.Insert()
41
+ if not isinstance(self._expression, exp.Insert):
42
+ msg = "Cannot set target table on a non-INSERT expression."
43
+ raise SQLBuilderError(msg)
44
+
45
+ setattr(self, "_table", table)
46
+ self._expression.set("this", exp.to_table(table))
47
+ return self
48
+
49
+
50
+ @trait
51
+ class InsertValuesMixin:
52
+ """Mixin providing VALUES and columns methods for INSERT builders."""
53
+
54
+ __slots__ = ()
55
+
56
+ # Type annotation for PyRight - this will be provided by the base class
57
+ _expression: Optional[exp.Expression]
58
+
59
+ _columns: Any # Provided by QueryBuilder
60
+
61
+ def add_parameter(self, value: Any, name: Optional[str] = None) -> tuple[Any, str]:
62
+ """Add parameter - provided by QueryBuilder."""
63
+ msg = "Method must be provided by QueryBuilder subclass"
64
+ raise NotImplementedError(msg)
65
+
66
+ def _generate_unique_parameter_name(self, base_name: str) -> str:
67
+ """Generate unique parameter name - provided by QueryBuilder."""
68
+ msg = "Method must be provided by QueryBuilder subclass"
69
+ raise NotImplementedError(msg)
70
+
71
+ def columns(self, *columns: Union[str, exp.Expression]) -> Self:
72
+ """Set the columns for the INSERT statement and synchronize the _columns attribute on the builder."""
73
+ if self._expression is None:
74
+ self._expression = exp.Insert()
75
+ if not isinstance(self._expression, exp.Insert):
76
+ msg = "Cannot set columns on a non-INSERT expression."
77
+ raise SQLBuilderError(msg)
78
+ column_exprs = [exp.column(col) if isinstance(col, str) else col for col in columns]
79
+ self._expression.set("columns", column_exprs)
80
+ try:
81
+ cols = self._columns
82
+ if not columns:
83
+ cols.clear()
84
+ else:
85
+ cols[:] = [col.name if isinstance(col, exp.Column) else str(col) for col in columns]
86
+ except AttributeError:
87
+ pass
88
+ return self
89
+
90
+ def values(self, *values: Any, **kwargs: Any) -> Self:
91
+ """Add a row of values to the INSERT statement.
92
+
93
+ Supports:
94
+ - values(val1, val2, val3)
95
+ - values(col1=val1, col2=val2)
96
+ - values(mapping)
97
+
98
+ Args:
99
+ *values: Either positional values or a single mapping.
100
+ **kwargs: Column-value pairs.
101
+
102
+ Returns:
103
+ The current builder instance for method chaining.
104
+ """
105
+ if self._expression is None:
106
+ self._expression = exp.Insert()
107
+ if not isinstance(self._expression, exp.Insert):
108
+ msg = "Cannot add values to a non-INSERT expression."
109
+ raise SQLBuilderError(msg)
110
+
111
+ if kwargs:
112
+ if values:
113
+ msg = "Cannot mix positional values with keyword values."
114
+ raise SQLBuilderError(msg)
115
+ try:
116
+ _columns = self._columns
117
+ if not _columns:
118
+ self.columns(*kwargs.keys())
119
+ except AttributeError:
120
+ pass
121
+ row_exprs = []
122
+ for col, val in kwargs.items():
123
+ if isinstance(val, exp.Expression):
124
+ row_exprs.append(val)
125
+ else:
126
+ column_name = col if isinstance(col, str) else str(col)
127
+ if "." in column_name:
128
+ column_name = column_name.split(".")[-1]
129
+ param_name = self._generate_unique_parameter_name(column_name)
130
+ _, param_name = self.add_parameter(val, name=param_name)
131
+ row_exprs.append(exp.var(param_name))
132
+ elif len(values) == 1 and hasattr(values[0], "items"):
133
+ mapping = values[0]
134
+ try:
135
+ _columns = self._columns
136
+ if not _columns:
137
+ self.columns(*mapping.keys())
138
+ except AttributeError:
139
+ pass
140
+ row_exprs = []
141
+ for col, val in mapping.items():
142
+ if isinstance(val, exp.Expression):
143
+ row_exprs.append(val)
144
+ else:
145
+ column_name = col if isinstance(col, str) else str(col)
146
+ if "." in column_name:
147
+ column_name = column_name.split(".")[-1]
148
+ param_name = self._generate_unique_parameter_name(column_name)
149
+ _, param_name = self.add_parameter(val, name=param_name)
150
+ row_exprs.append(exp.var(param_name))
151
+ else:
152
+ try:
153
+ _columns = self._columns
154
+ if _columns and len(values) != len(_columns):
155
+ msg = f"Number of values ({len(values)}) does not match the number of specified columns ({len(_columns)})."
156
+ raise SQLBuilderError(msg)
157
+ except AttributeError:
158
+ pass
159
+ row_exprs = []
160
+ for i, v in enumerate(values):
161
+ if isinstance(v, exp.Expression):
162
+ row_exprs.append(v)
163
+ else:
164
+ try:
165
+ _columns = self._columns
166
+ if _columns and i < len(_columns):
167
+ column_name = (
168
+ str(_columns[i]).split(".")[-1] if "." in str(_columns[i]) else str(_columns[i])
169
+ )
170
+ param_name = self._generate_unique_parameter_name(column_name)
171
+ else:
172
+ param_name = self._generate_unique_parameter_name(f"value_{i + 1}")
173
+ except AttributeError:
174
+ param_name = self._generate_unique_parameter_name(f"value_{i + 1}")
175
+ _, param_name = self.add_parameter(v, name=param_name)
176
+ row_exprs.append(exp.var(param_name))
177
+
178
+ values_expr = exp.Values(expressions=[row_exprs])
179
+ self._expression.set("expression", values_expr)
180
+ return self
181
+
182
+ def add_values(self, values: Sequence[Any]) -> Self:
183
+ """Add a row of values to the INSERT statement (alternative signature).
184
+
185
+ Args:
186
+ values: Sequence of values for the row.
187
+
188
+ Returns:
189
+ The current builder instance for method chaining.
190
+ """
191
+ return self.values(*values)
192
+
193
+
194
+ @trait
195
+ class InsertFromSelectMixin:
196
+ """Mixin providing INSERT ... SELECT support for INSERT builders."""
197
+
198
+ __slots__ = ()
199
+
200
+ # Type annotation for PyRight - this will be provided by the base class
201
+ _expression: Optional[exp.Expression]
202
+
203
+ _table: Any # Provided by QueryBuilder
204
+
205
+ def add_parameter(self, value: Any, name: Optional[str] = None) -> tuple[Any, str]:
206
+ """Add parameter - provided by QueryBuilder."""
207
+ msg = "Method must be provided by QueryBuilder subclass"
208
+ raise NotImplementedError(msg)
209
+
210
+ def from_select(self, select_builder: Any) -> Self:
211
+ """Sets the INSERT source to a SELECT statement.
212
+
213
+ Args:
214
+ select_builder: A SelectBuilder instance representing the SELECT query.
215
+
216
+ Returns:
217
+ The current builder instance for method chaining.
218
+
219
+ Raises:
220
+ SQLBuilderError: If the table is not set or the select_builder is invalid.
221
+ """
222
+ try:
223
+ if not self._table:
224
+ msg = "The target table must be set using .into() before adding values."
225
+ raise SQLBuilderError(msg)
226
+ except AttributeError:
227
+ msg = "The target table must be set using .into() before adding values."
228
+ raise SQLBuilderError(msg)
229
+ if self._expression is None:
230
+ self._expression = exp.Insert()
231
+ if not isinstance(self._expression, exp.Insert):
232
+ msg = "Cannot set INSERT source on a non-INSERT expression."
233
+ raise SQLBuilderError(msg)
234
+ subquery_parameters = select_builder._parameters
235
+ if subquery_parameters:
236
+ for p_name, p_value in subquery_parameters.items():
237
+ self.add_parameter(p_value, name=p_name)
238
+ select_expr = select_builder._expression
239
+ if select_expr and isinstance(select_expr, exp.Select):
240
+ self._expression.set("expression", select_expr.copy())
241
+ else:
242
+ msg = "SelectBuilder must have a valid SELECT expression."
243
+ raise SQLBuilderError(msg)
244
+ return self
@@ -0,0 +1,122 @@
1
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast
2
+
3
+ from mypy_extensions import trait
4
+ from sqlglot import exp
5
+ from typing_extensions import Self
6
+
7
+ from sqlspec.builder._parsing_utils import parse_table_expression
8
+ from sqlspec.exceptions import SQLBuilderError
9
+ from sqlspec.utils.type_guards import has_query_builder_parameters
10
+
11
+ if TYPE_CHECKING:
12
+ from sqlspec.protocols import SQLBuilderProtocol
13
+
14
+ __all__ = ("JoinClauseMixin",)
15
+
16
+
17
+ @trait
18
+ class JoinClauseMixin:
19
+ """Mixin providing JOIN clause methods for SELECT builders."""
20
+
21
+ __slots__ = ()
22
+
23
+ # Type annotation for PyRight - this will be provided by the base class
24
+ _expression: Optional[exp.Expression]
25
+
26
+ def join(
27
+ self,
28
+ table: Union[str, exp.Expression, Any],
29
+ on: Optional[Union[str, exp.Expression]] = None,
30
+ alias: Optional[str] = None,
31
+ join_type: str = "INNER",
32
+ ) -> Self:
33
+ builder = cast("SQLBuilderProtocol", self)
34
+ if builder._expression is None:
35
+ builder._expression = exp.Select()
36
+ if not isinstance(builder._expression, exp.Select):
37
+ msg = "JOIN clause is only supported for SELECT statements."
38
+ raise SQLBuilderError(msg)
39
+ table_expr: exp.Expression
40
+ if isinstance(table, str):
41
+ table_expr = parse_table_expression(table, alias)
42
+ elif has_query_builder_parameters(table):
43
+ if hasattr(table, "_expression") and getattr(table, "_expression", None) is not None:
44
+ table_expr_value = getattr(table, "_expression", None)
45
+ if table_expr_value is not None:
46
+ subquery_exp = exp.paren(table_expr_value)
47
+ else:
48
+ subquery_exp = exp.paren(exp.Anonymous(this=""))
49
+ table_expr = exp.alias_(subquery_exp, alias) if alias else subquery_exp
50
+ else:
51
+ subquery = table.build()
52
+ sql_str = subquery.sql if hasattr(subquery, "sql") and not callable(subquery.sql) else str(subquery)
53
+ subquery_exp = exp.paren(exp.maybe_parse(sql_str, dialect=getattr(builder, "dialect", None)))
54
+ table_expr = exp.alias_(subquery_exp, alias) if alias else subquery_exp
55
+ else:
56
+ table_expr = table
57
+ on_expr: Optional[exp.Expression] = None
58
+ if on is not None:
59
+ on_expr = exp.condition(on) if isinstance(on, str) else on
60
+ join_type_upper = join_type.upper()
61
+ if join_type_upper == "INNER":
62
+ join_expr = exp.Join(this=table_expr, on=on_expr)
63
+ elif join_type_upper == "LEFT":
64
+ join_expr = exp.Join(this=table_expr, on=on_expr, side="LEFT")
65
+ elif join_type_upper == "RIGHT":
66
+ join_expr = exp.Join(this=table_expr, on=on_expr, side="RIGHT")
67
+ elif join_type_upper == "FULL":
68
+ join_expr = exp.Join(this=table_expr, on=on_expr, side="FULL", kind="OUTER")
69
+ else:
70
+ msg = f"Unsupported join type: {join_type}"
71
+ raise SQLBuilderError(msg)
72
+ builder._expression = builder._expression.join(join_expr, copy=False)
73
+ return cast("Self", builder)
74
+
75
+ def inner_join(
76
+ self, table: Union[str, exp.Expression, Any], on: Union[str, exp.Expression], alias: Optional[str] = None
77
+ ) -> Self:
78
+ return self.join(table, on, alias, "INNER")
79
+
80
+ def left_join(
81
+ self, table: Union[str, exp.Expression, Any], on: Union[str, exp.Expression], alias: Optional[str] = None
82
+ ) -> Self:
83
+ return self.join(table, on, alias, "LEFT")
84
+
85
+ def right_join(
86
+ self, table: Union[str, exp.Expression, Any], on: Union[str, exp.Expression], alias: Optional[str] = None
87
+ ) -> Self:
88
+ return self.join(table, on, alias, "RIGHT")
89
+
90
+ def full_join(
91
+ self, table: Union[str, exp.Expression, Any], on: Union[str, exp.Expression], alias: Optional[str] = None
92
+ ) -> Self:
93
+ return self.join(table, on, alias, "FULL")
94
+
95
+ def cross_join(self, table: Union[str, exp.Expression, Any], alias: Optional[str] = None) -> Self:
96
+ builder = cast("SQLBuilderProtocol", self)
97
+ if builder._expression is None:
98
+ builder._expression = exp.Select()
99
+ if not isinstance(builder._expression, exp.Select):
100
+ msg = "Cannot add cross join to a non-SELECT expression."
101
+ raise SQLBuilderError(msg)
102
+ table_expr: exp.Expression
103
+ if isinstance(table, str):
104
+ table_expr = parse_table_expression(table, alias)
105
+ elif has_query_builder_parameters(table):
106
+ if hasattr(table, "_expression") and getattr(table, "_expression", None) is not None:
107
+ table_expr_value = getattr(table, "_expression", None)
108
+ if table_expr_value is not None:
109
+ subquery_exp = exp.paren(table_expr_value)
110
+ else:
111
+ subquery_exp = exp.paren(exp.Anonymous(this=""))
112
+ table_expr = exp.alias_(subquery_exp, alias) if alias else subquery_exp
113
+ else:
114
+ subquery = table.build()
115
+ sql_str = subquery.sql if hasattr(subquery, "sql") and not callable(subquery.sql) else str(subquery)
116
+ subquery_exp = exp.paren(exp.maybe_parse(sql_str, dialect=getattr(builder, "dialect", None)))
117
+ table_expr = exp.alias_(subquery_exp, alias) if alias else subquery_exp
118
+ else:
119
+ table_expr = table
120
+ join_expr = exp.Join(this=table_expr, kind="CROSS")
121
+ builder._expression = builder._expression.join(join_expr, copy=False)
122
+ return cast("Self", builder)