Skip to content

Commit 163b85b

Browse files
authored
Merge branch 'SQLMesh:main' into feature/DRM/resolve-indirect-non-breaking-deployable-representative-mismatch
2 parents 8b45e3f + 2c30f83 commit 163b85b

30 files changed

Lines changed: 423 additions & 73 deletions

File tree

‎.devcontainer/devcontainer-lock.json‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@
1010
"resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:4fa87399214366e320d489991769c4f3f461e1ffe461f54eea78a41b34945bb5",
1111
"integrity": "sha256:4fa87399214366e320d489991769c4f3f461e1ffe461f54eea78a41b34945bb5"
1212
},
13-
"ghcr.io/devcontainers/features/java:1": {
14-
"version": "1.8.1",
15-
"resolved": "ghcr.io/devcontainers/features/java@sha256:8157bab2d8d71e40b2f3128c162fab763e2b11038fdd33784549290a5d386b48",
16-
"integrity": "sha256:8157bab2d8d71e40b2f3128c162fab763e2b11038fdd33784549290a5d386b48"
17-
},
1813
"ghcr.io/devcontainers/features/python:1": {
1914
"version": "1.8.0",
2015
"resolved": "ghcr.io/devcontainers/features/python@sha256:fbcad6955caeecc5ad3f7886baf652e25cba5225a6c4c2287c536de2e5607511",

‎.devcontainer/devcontainer.json‎

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,12 @@
66
"ghcr.io/devcontainers/features/python:1": {
77
"version": "3.12"
88
},
9-
"ghcr.io/devcontainers/features/java:1": {
10-
"version": "21"
11-
},
129
"ghcr.io/devcontainers/features/docker-in-docker:4": {}
1310
},
1411
"postCreateCommand": "bash .devcontainer/post-create-command.sh",
1512
"customizations": {
1613
"vscode": {
17-
"extensions": [
18-
"ms-python.python",
19-
"ms-python.vscode-pylance"
20-
]
14+
"extensions": ["ms-python.python", "ms-python.vscode-pylance"]
2115
}
2216
},
2317
"remoteUser": "vscode"

‎.github/workflows/pr.yaml‎

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ jobs:
1616
outputs:
1717
python: ${{ steps.filter.outputs.python }}
1818
client: ${{ steps.filter.outputs.client }}
19+
vscode: ${{ steps.filter.outputs.vscode }}
1920
ci: ${{ steps.filter.outputs.ci }}
2021
steps:
2122
- uses: actions/checkout@v7
@@ -34,6 +35,8 @@ jobs:
3435
- 'pyproject.toml'
3536
client:
3637
- 'web/client/**'
38+
vscode:
39+
- 'vscode/**'
3740
ci:
3841
- '.github/**'
3942
- 'Makefile'
@@ -188,9 +191,10 @@ jobs:
188191

189192
ui-style:
190193
needs: [changes]
191-
if: false
192-
# needs.changes.outputs.client == 'true' || needs.changes.outputs.ci ==
193-
# 'true' || github.ref == 'refs/heads/main'
194+
if:
195+
needs.changes.outputs.client == 'true' || needs.changes.outputs.vscode ==
196+
'true' || needs.changes.outputs.ci == 'true' || github.ref ==
197+
'refs/heads/main'
194198
runs-on: ubuntu-latest
195199
steps:
196200
- uses: actions/checkout@v7
@@ -252,7 +256,17 @@ jobs:
252256
fail-fast: false
253257
matrix:
254258
engine:
255-
[duckdb, postgres, mysql, mssql, trino, spark, clickhouse, risingwave, starrocks]
259+
[
260+
duckdb,
261+
postgres,
262+
mysql,
263+
mssql,
264+
trino,
265+
spark,
266+
clickhouse,
267+
risingwave,
268+
starrocks,
269+
]
256270
env:
257271
PYTEST_XDIST_AUTO_NUM_WORKERS: 2
258272
SQLMESH__DISABLE_ANONYMIZED_ANALYTICS: '1'
@@ -393,10 +407,13 @@ jobs:
393407
retention-days: 7
394408

395409
test-vscode:
410+
needs: changes
411+
if:
412+
needs.changes.outputs.vscode == 'true' || needs.changes.outputs.ci ==
413+
'true' || github.ref == 'refs/heads/main'
396414
env:
397415
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
398416
runs-on: ubuntu-latest
399-
if: false
400417
steps:
401418
- uses: actions/checkout@v7
402419
- uses: actions/setup-node@v7
@@ -457,7 +474,19 @@ jobs:
457474
strategy:
458475
fail-fast: false
459476
matrix:
460-
dbt-version: ['1.3', '1.4', '1.5', '1.6', '1.7', '1.8', '1.9', '1.10', '1.11']
477+
dbt-version:
478+
[
479+
'1.3',
480+
'1.4',
481+
'1.5',
482+
'1.6',
483+
'1.7',
484+
'1.8',
485+
'1.9',
486+
'1.10',
487+
'1.11',
488+
'1.12',
489+
]
461490
steps:
462491
- uses: actions/checkout@v7
463492
- name: Set up Python

‎Makefile‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ install-dev-dbt-%:
3333
echo "Installing dbt version: $$version"; \
3434
cp pyproject.toml pyproject.toml.backup; \
3535
$(SED_INPLACE) 's/"pydantic>=2.0.0"/"pydantic"/g' pyproject.toml; \
36-
if [ "$$version" = "1.10.0" ] || [ "$$version" = "1.11.0" ]; then \
36+
if [ "$$version" = "1.10.0" ] || [ "$$version" = "1.11.0" ] || [ "$$version" = "1.12.0" ]; then \
3737
echo "Applying special handling for dbt $$version"; \
3838
$(SED_INPLACE) -E 's/"(dbt-core)[^"]*"/"\1~='"$$version"'"/g' pyproject.toml; \
3939
$(SED_INPLACE) -E 's/"(dbt-(bigquery|duckdb|snowflake|athena-community|clickhouse|redshift|trino))[^"]*"/"\1"/g' pyproject.toml; \
@@ -132,13 +132,13 @@ engine-up: engine-clickhouse-up engine-mssql-up engine-mysql-up engine-postgres-
132132
engine-down: engine-clickhouse-down engine-mssql-down engine-mysql-down engine-postgres-down engine-spark-down engine-trino-down
133133

134134
fast-test:
135-
pytest -n auto -m "fast and not cicdonly" --junitxml=test-results/junit-fast-test.xml && pytest -m "isolated" && pytest -m "registry_isolation" && pytest -m "dialect_isolated"
135+
pytest -n auto -m "fast and not cicdonly and not isolated" --junitxml=test-results/junit-fast-test.xml && pytest -m "isolated and not slow" && pytest -m "registry_isolation" && pytest -m "dialect_isolated"
136136

137137
slow-test:
138-
pytest -n auto -m "(fast or slow) and not cicdonly" && pytest -m "isolated" && pytest -m "registry_isolation" && pytest -m "dialect_isolated"
138+
pytest -n auto -m "(fast or slow) and not cicdonly and not isolated" && pytest -m "isolated" && pytest -m "registry_isolation" && pytest -m "dialect_isolated"
139139

140140
cicd-test:
141-
pytest -n auto -m "(fast or slow) and not pyspark" --junitxml=test-results/junit-cicd.xml && pytest -m "pyspark" && pytest -m "isolated" && pytest -m "registry_isolation" && pytest -m "dialect_isolated"
141+
pytest -n auto -m "(fast or slow) and not pyspark and not isolated" --junitxml=test-results/junit-cicd.xml && pytest -m "pyspark" && pytest -m "isolated and not pyspark" && pytest -m "registry_isolation" && pytest -m "dialect_isolated"
142142

143143
core-fast-test:
144144
pytest -n auto -m "fast and not web and not github and not dbt and not jupyter"

‎sqlmesh/core/engine_adapter/base.py‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,8 @@ def clone_table(
10941094
replace: bool = False,
10951095
exists: bool = True,
10961096
clone_kwargs: t.Optional[t.Dict[str, t.Any]] = None,
1097+
table_format: t.Optional[str] = None,
1098+
table_kind: t.Optional[str] = None,
10971099
**kwargs: t.Any,
10981100
) -> None:
10991101
"""Creates a table with the target name by cloning the source table.
@@ -1103,6 +1105,10 @@ def clone_table(
11031105
source_table_name: The name of the source table that should be cloned.
11041106
replace: Whether or not to replace an existing table.
11051107
exists: Indicates whether to include the IF NOT EXISTS check.
1108+
clone_kwargs: Additional arguments for the CLONE clause.
1109+
table_format: The table format of the source table, if any. Engines that require
1110+
format-specific DDL to clone a table use it to derive `table_kind`.
1111+
table_kind: The kind of table to create. Defaults to `TABLE`.
11061112
"""
11071113
if not self.SUPPORTS_CLONING:
11081114
raise NotImplementedError(f"Engine does not support cloning: {type(self)}")
@@ -1111,7 +1117,7 @@ def clone_table(
11111117
self.execute(
11121118
exp.Create(
11131119
this=exp.to_table(target_table_name),
1114-
kind="TABLE",
1120+
kind=table_kind or "TABLE",
11151121
replace=replace,
11161122
exists=exists,
11171123
clone=exp.Clone(
@@ -1214,9 +1220,15 @@ def get_alter_operations(
12141220
def alter_table(
12151221
self,
12161222
alter_expressions: t.Union[t.List[exp.Alter], t.List[TableAlterOperation]],
1223+
table_format: t.Optional[str] = None,
12171224
) -> None:
12181225
"""
12191226
Performs the alter statements to change the current table into the structure of the target table.
1227+
1228+
Args:
1229+
alter_expressions: The alter operations to apply.
1230+
table_format: The table format of the target table, if any. Engines that require
1231+
format-specific DDL to alter a table use it to adjust the generated statements.
12201232
"""
12211233
with self.transaction():
12221234
for alter_expression in [

‎sqlmesh/core/engine_adapter/bigquery.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ def create_mapping_schema(
405405
def alter_table(
406406
self,
407407
alter_expressions: t.Union[t.List[exp.Alter], t.List[TableAlterOperation]],
408+
table_format: t.Optional[str] = None,
408409
) -> None:
409410
"""
410411
Performs the alter statements to change the current table into the structure of the target table,

‎sqlmesh/core/engine_adapter/clickhouse.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ def delete_from(self, table_name: TableName, where: t.Union[str, exp.Expr]) -> N
699699
def alter_table(
700700
self,
701701
alter_expressions: t.Union[t.List[exp.Alter], t.List[TableAlterOperation]],
702+
table_format: t.Optional[str] = None,
702703
) -> None:
703704
"""
704705
Performs the alter statements to change the current table into the structure of the target table.

‎sqlmesh/core/engine_adapter/databricks.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ def clone_table(
386386
replace: bool = False,
387387
exists: bool = True,
388388
clone_kwargs: t.Optional[t.Dict[str, t.Any]] = None,
389+
table_format: t.Optional[str] = None,
390+
table_kind: t.Optional[str] = None,
389391
**kwargs: t.Any,
390392
) -> None:
391393
clone_kwargs = clone_kwargs or {}
@@ -395,6 +397,8 @@ def clone_table(
395397
source_table_name,
396398
replace=replace,
397399
clone_kwargs=clone_kwargs,
400+
table_format=table_format,
401+
table_kind=table_kind,
398402
**kwargs,
399403
)
400404

‎sqlmesh/core/engine_adapter/fabric.py‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,9 @@ def set_current_catalog(self, catalog_name: t.Optional[str]) -> None:
225225
self._target_catalog = target_catalog
226226

227227
def alter_table(
228-
self, alter_expressions: t.Union[t.List[exp.Alter], t.List[TableAlterOperation]]
228+
self,
229+
alter_expressions: t.Union[t.List[exp.Alter], t.List[TableAlterOperation]],
230+
table_format: t.Optional[str] = None,
229231
) -> None:
230232
"""
231233
Applies alter expressions to a table. Fabric has limited support for ALTER TABLE,

‎sqlmesh/core/engine_adapter/snowflake.py‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
SourceQuery,
2525
set_catalog,
2626
)
27+
from sqlmesh.core.schema_diff import TableAlterOperation
2728
from sqlmesh.utils import optional_import, get_source_columns_to_types
2829
from sqlmesh.utils.errors import SQLMeshError
2930
from sqlmesh.utils.pandas import columns_to_types_from_dtypes
@@ -667,6 +668,8 @@ def clone_table(
667668
replace: bool = False,
668669
exists: bool = True,
669670
clone_kwargs: t.Optional[t.Dict[str, t.Any]] = None,
671+
table_format: t.Optional[str] = None,
672+
table_kind: t.Optional[str] = None,
670673
**kwargs: t.Any,
671674
) -> None:
672675
# The Snowflake adapter should use the transient property to clone transient tables
@@ -675,14 +678,43 @@ def clone_table(
675678
if isinstance(table_type, exp.TransientProperty):
676679
kwargs["properties"] = exp.Properties(expressions=[table_type])
677680

681+
# Snowflake rejects `CREATE TABLE ... CLONE` for Iceberg tables, it requires
682+
# `CREATE ICEBERG TABLE ... CLONE` instead
683+
if table_format and not table_kind:
684+
table_kind = f"{table_format.upper()} TABLE"
685+
678686
super().clone_table(
679687
target_table_name,
680688
source_table_name,
681689
replace=replace,
682690
clone_kwargs=clone_kwargs,
691+
table_kind=table_kind,
683692
**kwargs,
684693
)
685694

695+
def alter_table(
696+
self,
697+
alter_expressions: t.Union[t.List[exp.Alter], t.List[TableAlterOperation]],
698+
table_format: t.Optional[str] = None,
699+
) -> None:
700+
# Snowflake rejects `ALTER TABLE` for Iceberg tables, it requires
701+
# `ALTER ICEBERG TABLE` instead
702+
if table_format:
703+
table_kind = f"{table_format.upper()} TABLE"
704+
resolved_expressions = []
705+
for alter_expression in alter_expressions:
706+
resolved_expression = (
707+
alter_expression.expression
708+
if isinstance(alter_expression, TableAlterOperation)
709+
else alter_expression.copy()
710+
)
711+
resolved_expression.set("kind", table_kind)
712+
resolved_expressions.append(resolved_expression)
713+
714+
super().alter_table(resolved_expressions)
715+
else:
716+
super().alter_table(alter_expressions)
717+
686718
@t.overload
687719
def _columns_to_types(
688720
self,

0 commit comments

Comments
 (0)