sqlmesh 0.198.1.dev5__py3-none-any.whl → 0.198.1.dev7__py3-none-any.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.
sqlmesh/_version.py CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '0.198.1.dev5'
21
- __version_tuple__ = version_tuple = (0, 198, 1, 'dev5')
20
+ __version__ = version = '0.198.1.dev7'
21
+ __version_tuple__ = version_tuple = (0, 198, 1, 'dev7')
sqlmesh/core/dialect.py CHANGED
@@ -1388,17 +1388,27 @@ def is_meta_expression(v: t.Any) -> bool:
1388
1388
  return isinstance(v, (Audit, Metric, Model))
1389
1389
 
1390
1390
 
1391
- def replace_merge_table_aliases(expression: exp.Expression) -> exp.Expression:
1391
+ def replace_merge_table_aliases(
1392
+ expression: exp.Expression, dialect: t.Optional[str] = None
1393
+ ) -> exp.Expression:
1392
1394
  """
1393
1395
  Resolves references from the "source" and "target" tables (or their DBT equivalents)
1394
1396
  with the corresponding SQLMesh merge aliases (MERGE_SOURCE_ALIAS and MERGE_TARGET_ALIAS)
1395
1397
  """
1396
1398
  from sqlmesh.core.engine_adapter.base import MERGE_SOURCE_ALIAS, MERGE_TARGET_ALIAS
1397
1399
 
1400
+ normalized_merge_source_alias = quote_identifiers(
1401
+ normalize_identifiers(exp.to_identifier(MERGE_SOURCE_ALIAS), dialect), dialect=dialect
1402
+ )
1403
+
1404
+ normalized_merge_target_alias = quote_identifiers(
1405
+ normalize_identifiers(exp.to_identifier(MERGE_TARGET_ALIAS), dialect), dialect=dialect
1406
+ )
1407
+
1398
1408
  if isinstance(expression, exp.Column) and (first_part := expression.parts[0]):
1399
1409
  if first_part.this.lower() in ("target", "dbt_internal_dest", "__merge_target__"):
1400
- first_part.replace(exp.to_identifier(MERGE_TARGET_ALIAS))
1410
+ first_part.replace(normalized_merge_target_alias)
1401
1411
  elif first_part.this.lower() in ("source", "dbt_internal_source", "__merge_source__"):
1402
- first_part.replace(exp.to_identifier(MERGE_SOURCE_ALIAS))
1412
+ first_part.replace(normalized_merge_source_alias)
1403
1413
 
1404
1414
  return expression
@@ -653,7 +653,7 @@ class _Model(ModelMeta, frozen=True):
653
653
  )
654
654
  if len(rendered_exprs) != 1:
655
655
  raise SQLMeshError(f"Expected one expression but got {len(rendered_exprs)}")
656
- return rendered_exprs[0].transform(d.replace_merge_table_aliases)
656
+ return rendered_exprs[0].transform(d.replace_merge_table_aliases, dialect=self.dialect)
657
657
 
658
658
  def _render_properties(
659
659
  self, properties: t.Dict[str, exp.Expression] | SessionProperties, **render_kwargs: t.Any
@@ -34,6 +34,7 @@ from sqlmesh.utils.pydantic import (
34
34
  get_dialect,
35
35
  validate_string,
36
36
  positive_int_validator,
37
+ validate_expression,
37
38
  )
38
39
 
39
40
 
@@ -467,15 +468,20 @@ class IncrementalByUniqueKeyKind(_IncrementalBy):
467
468
  return v
468
469
  if isinstance(v, list):
469
470
  v = " ".join(v)
471
+
472
+ dialect = get_dialect(info.data)
473
+
470
474
  if isinstance(v, str):
471
475
  # Whens wrap the WHEN clauses, but the parentheses aren't parsed by sqlglot
472
476
  v = v.strip()
473
477
  if v.startswith("("):
474
478
  v = v[1:-1]
475
479
 
476
- return t.cast(exp.Whens, d.parse_one(v, into=exp.Whens, dialect=get_dialect(info.data)))
480
+ v = t.cast(exp.Whens, d.parse_one(v, into=exp.Whens, dialect=dialect))
481
+ else:
482
+ v = t.cast(exp.Whens, v.transform(d.replace_merge_table_aliases, dialect=dialect))
477
483
 
478
- return t.cast(exp.Whens, v.transform(d.replace_merge_table_aliases))
484
+ return validate_expression(v, dialect=dialect)
479
485
 
480
486
  @field_validator("merge_filter", mode="before")
481
487
  def _merge_filter_validator(
@@ -485,11 +491,16 @@ class IncrementalByUniqueKeyKind(_IncrementalBy):
485
491
  ) -> t.Optional[exp.Expression]:
486
492
  if v is None:
487
493
  return v
494
+
495
+ dialect = get_dialect(info.data)
496
+
488
497
  if isinstance(v, str):
489
498
  v = v.strip()
490
- return d.parse_one(v, dialect=get_dialect(info.data))
499
+ v = d.parse_one(v, dialect=dialect)
500
+ else:
501
+ v = v.transform(d.replace_merge_table_aliases, dialect=dialect)
491
502
 
492
- return v.transform(d.replace_merge_table_aliases)
503
+ return validate_expression(v, dialect=dialect)
493
504
 
494
505
  @property
495
506
  def data_hash_values(self) -> t.List[t.Optional[str]]:
@@ -0,0 +1,9 @@
1
+ """
2
+ Normalize and quote the when_matched and merge_filter properties of IncrementalByUniqueKeyKind
3
+ to match how other properties (such as time_column and partitioned_by) are handled and to
4
+ prevent un-normalized identifiers being quoted at the EngineAdapter level
5
+ """
6
+
7
+
8
+ def migrate(state_sync, **kwargs): # type: ignore
9
+ pass
sqlmesh/utils/pydantic.py CHANGED
@@ -16,6 +16,8 @@ from sqlmesh.core import dialect as d
16
16
  from sqlmesh.utils import str_to_bool
17
17
 
18
18
  if t.TYPE_CHECKING:
19
+ from sqlglot._typing import E
20
+
19
21
  Model = t.TypeVar("Model", bound="PydanticModel")
20
22
 
21
23
 
@@ -193,6 +195,12 @@ def validate_string(v: t.Any) -> str:
193
195
  return str(v)
194
196
 
195
197
 
198
+ def validate_expression(expression: E, dialect: str) -> E:
199
+ # this normalizes and quotes identifiers in the given expression according the specified dialect
200
+ # it also sets expression.meta["dialect"] so that when we serialize for state, the expression is serialized in the correct dialect
201
+ return _get_field(expression, {"dialect": dialect}) # type: ignore
202
+
203
+
196
204
  def bool_validator(v: t.Any) -> bool:
197
205
  if isinstance(v, exp.Boolean):
198
206
  return v.this
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlmesh
3
- Version: 0.198.1.dev5
3
+ Version: 0.198.1.dev7
4
4
  Summary: Next-generation data transformation framework
5
5
  Author-email: "TobikoData Inc." <engineering@tobikodata.com>
6
6
  License: Apache License
@@ -1,5 +1,5 @@
1
1
  sqlmesh/__init__.py,sha256=QjwaamJIdW7voXoS880yAx7tHm-Im4_mqGA-XJgafos,7631
2
- sqlmesh/_version.py,sha256=560FhDSyJ6deWB4PAGmNCQtZoDAnfCdgsTJtlDmIOtU,528
2
+ sqlmesh/_version.py,sha256=BvGtG8_xd6e0Xehm4j-ZzhdPofdCenepvMzQP9urMLs,528
3
3
  sqlmesh/magics.py,sha256=R9U0Mp9ZQhDYe751nxAQDLaMv3zLAR4HcTdIflKTmEE,41709
4
4
  sqlmesh/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  sqlmesh/cicd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -15,7 +15,7 @@ sqlmesh/core/console.py,sha256=HInr6MOcxgn8Z-B9fAoghoDXbBEZqkB5ClyZF-fRP58,15903
15
15
  sqlmesh/core/constants.py,sha256=gUABXWYgH_XOSbaZAJsR5o1dmA61JDCvBDyxqqXX3LM,2630
16
16
  sqlmesh/core/context.py,sha256=XQFLCzpiO8yYgIcgP0J1fG9mYBzrveaqGB8ZINR6W5A,119362
17
17
  sqlmesh/core/context_diff.py,sha256=TCzM8egBE35DskpouOB-GQM2Qf5iUHWbRgiB5yZ6tzg,21552
18
- sqlmesh/core/dialect.py,sha256=KOAHrZ1F9zUbCC3vZeZmijOrjOhOhhRWJ9n1nvvTTRo,49821
18
+ sqlmesh/core/dialect.py,sha256=1ykYwb9WZn_nCaX08PcQ0BJh2Pihv9SPvoMNjpMeCfs,50158
19
19
  sqlmesh/core/environment.py,sha256=7DbJX0r5nZRU3LhcgIxbSV-JosQYDjAt3V5Wc2Fpns8,13005
20
20
  sqlmesh/core/lineage.py,sha256=zjB0Zfamo2Fja2r5SSZPMbrEKTXr1WjozZPVqvxdybI,3143
21
21
  sqlmesh/core/loader.py,sha256=98lSZMe6pJUx1gHkLeMLkkxOG9wgRlIQlK-qvk9DWgc,40530
@@ -88,8 +88,8 @@ sqlmesh/core/model/__init__.py,sha256=C8GRZ53xuXEA9hQv3BQS9pNNyd9rZ06R_B96UYGhDu
88
88
  sqlmesh/core/model/cache.py,sha256=csun0RJguHzKX6-qITcOs4fVP4f8_Ts8qiUVV4sHY6Q,7869
89
89
  sqlmesh/core/model/common.py,sha256=PcQS3rHFNIXV_Z1dGwLQ7gLPbYVlrbWGGKAyc58-9Xk,17379
90
90
  sqlmesh/core/model/decorator.py,sha256=wUUg5t0K559tV9Pqt6FE2EWXt5TPGb4wF2Yg4B4hX4w,9251
91
- sqlmesh/core/model/definition.py,sha256=6visJ4GBdQ7Stl2T9_J4E_fQlV1o8xoLCuuStekHZYs,111250
92
- sqlmesh/core/model/kind.py,sha256=_SBjhrTUrCGkmcsKmabbmBIe1s_6aMIEPEaQh0cDIok,36109
91
+ sqlmesh/core/model/definition.py,sha256=bVvdPhQxtRwqWe-fCBuslOPanWPPxK4vcRrbI-Dl2rk,111272
92
+ sqlmesh/core/model/kind.py,sha256=8Dp8yiTiXltboZWrB2FJ-LQ3zx4Fv_5Tj0KdUIPwCHI,36358
93
93
  sqlmesh/core/model/meta.py,sha256=D9InI9M2-IXeb34vkXNQSLALL8xVXjZ_LXwI-Tqxm7I,21197
94
94
  sqlmesh/core/model/schema.py,sha256=OClbAeA8LpW-IiSiLT_TlDWkEqmIIvSk0GXq8SWI-GQ,3443
95
95
  sqlmesh/core/model/seed.py,sha256=a0M-1zY1gOkN5ph2GQyataEdBSCtq50YjeFk2LyvInI,5058
@@ -260,6 +260,7 @@ sqlmesh/migrations/v0080_add_batch_size_to_scd_type_2_models.py,sha256=JvZ0xGEtd
260
260
  sqlmesh/migrations/v0081_update_partitioned_by.py,sha256=Rj9RDd7WBonbGfTJx3vAqSvq17F4pbGAhcrH6EtShmA,2896
261
261
  sqlmesh/migrations/v0082_warn_if_incorrectly_duplicated_statements.py,sha256=K-Z0ghTCFSZuAYzNSUXF4L8axihPemM15EOXHcqkK3s,2489
262
262
  sqlmesh/migrations/v0083_use_sql_for_scd_time_data_type_data_hash.py,sha256=0r-SlncPec4TBpnQTeblPsiIjIOVKc10GjBVbFPGcFA,148
263
+ sqlmesh/migrations/v0084_normalize_quote_when_matched_and_merge_filter.py,sha256=w1TbhvB98czuq5VZxsfcQE2w7o-nd96aKEIG-M1dn6A,329
263
264
  sqlmesh/schedulers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
264
265
  sqlmesh/utils/__init__.py,sha256=51VqA2etTZ6kX54250s1hN5ui7D89OeUTUQ9kgMze7s,11554
265
266
  sqlmesh/utils/aws.py,sha256=krxyhrKtsMJDEjT567UbGZogjJ9JRHkvAV-Cg3FVndM,1062
@@ -279,11 +280,11 @@ sqlmesh/utils/metaprogramming.py,sha256=ebN5p4Boi9VmsoNVsoUIaW3obgsrtZ6Gt1FlgbA-
279
280
  sqlmesh/utils/migration.py,sha256=R7Ck6FX-LfcujGy7sgS0kDWlK-xAEBODr3gqIQ8gC08,835
280
281
  sqlmesh/utils/pandas.py,sha256=FytTSLcRNtO0-YMvpoDBkkut3yoQJR9mBSKpif8lxug,2497
281
282
  sqlmesh/utils/process.py,sha256=vpXcpJ1eIbivs7gZdwTKSJI7OS6kKBebnaBzz75ykvs,2428
282
- sqlmesh/utils/pydantic.py,sha256=I898jAFqa3qU6lG2uPpRebVFncOUo8ZrLWM_R3K3DHU,11685
283
+ sqlmesh/utils/pydantic.py,sha256=o_NsXbIpDqNpUA1Uc5xF0ZzoXQYYB0DfHwdRxBwXPNk,12089
283
284
  sqlmesh/utils/rich.py,sha256=BpB47G0-JcU41LkGkeGKroexj4NOV5fox4-GOIXPgIc,3545
284
285
  sqlmesh/utils/windows.py,sha256=r7Yin4WEwbvH7sKA3hOJtRsclmscNuBeCklCfVPvtQs,611
285
286
  sqlmesh/utils/yaml.py,sha256=hvo5lmybYLcIx4p6CQwufS8X4MbwS60lEBnCmYJCXmU,2336
286
- sqlmesh-0.198.1.dev5.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
287
+ sqlmesh-0.198.1.dev7.dist-info/licenses/LICENSE,sha256=OlMefUjgWJdULtf84BLW0AZZcY8DwdgQqb_1j2862j8,11346
287
288
  web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
288
289
  web/client/dist/index.html,sha256=kNpFjWxt34Pf-P-cROtPWi3GNSVk6zqA3eoN9tlZXI0,5472
289
290
  web/client/dist/assets/Audits-DKgXravk.js,sha256=SaVQhNlislD_yQc_KivO7SPi1JH0ts1GnDPD5Zssutw,1041
@@ -401,8 +402,8 @@ web/server/api/endpoints/models.py,sha256=ud-lRwriyI_OYg9tZchrBgeiXELiRTLNEodraf
401
402
  web/server/api/endpoints/modules.py,sha256=8hqqgonGay_mJmpCw0IdbjsPhWlQH2VLdKAqha-myac,468
402
403
  web/server/api/endpoints/plan.py,sha256=bbbY50W_2MsZSTxOHWMKz0tbIm75nsRSlPy8GI2fg9Q,9306
403
404
  web/server/api/endpoints/table_diff.py,sha256=SCy3-pr5x6bEEiOaZGCDbiHQhpgxwmnz3Acqa2Ie6jI,2090
404
- sqlmesh-0.198.1.dev5.dist-info/METADATA,sha256=yTcY3QnM3HtDvNaoybW0HsLBtI-lUoZfEZi260DU7sM,26658
405
- sqlmesh-0.198.1.dev5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
406
- sqlmesh-0.198.1.dev5.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
407
- sqlmesh-0.198.1.dev5.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
408
- sqlmesh-0.198.1.dev5.dist-info/RECORD,,
405
+ sqlmesh-0.198.1.dev7.dist-info/METADATA,sha256=zhVHdoWo4cch6iQ206jH9EwTFCtIe9pDX-reE8wZLHE,26658
406
+ sqlmesh-0.198.1.dev7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
407
+ sqlmesh-0.198.1.dev7.dist-info/entry_points.txt,sha256=pIYKtg-u-uO7BK_Y0qrdmfyj0bYrcMc3Xiqr5WE3VFk,121
408
+ sqlmesh-0.198.1.dev7.dist-info/top_level.txt,sha256=bspjo5vjELQkuN0qKuTFIbsrUt3Zeo8D2mlKeHG1LdE,12
409
+ sqlmesh-0.198.1.dev7.dist-info/RECORD,,