From ac9ccbd922f19479d794efacf610aab80f05bb93 Mon Sep 17 00:00:00 2001 From: Axell Padilla <68310020+axellpadilla@users.noreply.github.com> Date: Sun, 2 Aug 2026 20:31:52 +0000 Subject: [PATCH] feat(sqlserver): add SqlServer arms across adapter_impl.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolves all 33 E0004 non-exhaustive-match errors in adapter_impl.rs that blocked a full dbt-adapter crate build, by adding a SqlServer arm (or joining an existing group) at every site the compiler flagged. Grouping decisions, verified against v1 dbt-sqlserver and the shared macro packages rather than assumed identical to Fabric: - valid_incremental_strategies: matches Fabric's set exactly — v1's SQLServerAdapter.valid_incremental_strategies() returns the same four strategies. - list_schemas_inner's schema column name ("schema"): confirmed via v1's sqlserver__list_schemas, which selects `name as [schema]`. - standardize_grants_dict: joins the Postgres/Bigquery/DuckDB/Alt group (grantee/privilege_type columns), not the "grants not implemented" bucket — v1's sqlserver__get_show_grant_sql selects exactly those two column names, and SQLServerAdapter doesn't override standardize_grants_dict, so it falls through to that same base implementation. - truncate_relation and get_columns_in_relation's macro-dispatch group: v1 has sqlserver__truncate_relation and sqlserver__get_columns_in_relation macros, so SqlServer joins the macro-based groups rather than any unimplemented bucket. - get_constraint_support: v1's SQLServerAdapter.CONSTRAINT_SUPPORT overrides all five constraint types to Enforced (including Check, unlike Fabric which marks Check NotSupported) — ported as its own block rather than folded into Fabric's. - verify_database: this method is only invoked from the dbt-postgres and dbt-redshift macro packages (grep confirms no other package calls adapter.verify_database), which SQL Server's macro package never dispatches into, so SqlServer joins the "unimplemented" bucket alongside Fabric/Snowflake/Databricks rather than the Postgres/DuckDB/Alt/ClickHouse single-database-check group — despite SQL Server otherwise supporting cross-database three-part names. - Every purely BigQuery- or Databricks-specific method (partition config, dataset location, table options, DBR capabilities, Iceberg helpers, etc.) gets SqlServer added to the existing "unimplemented" bucket alongside every other non-BigQuery/non-Databricks adapter. - adapter_specific_behavior_flags: returns vec![] for SqlServer. v1 registers 5 behavior flags, but 4 (default_schema_concat, native_string_types, safe_type_expansion, use_dbt_transactions) are staying on their v1 default with no alternate code path in the Rust adapter yet, and the 5th (disable_empty_relation_aliases) is out of scope here — so none are registered rather than declaring toggles the adapter doesn't yet honor. Follow-up if/when those paths land. Closes #7 --- .../dbt-adapter/src/adapter/adapter_impl.rs | 145 ++++++++++-------- 1 file changed, 77 insertions(+), 68 deletions(-) diff --git a/crates/dbt-adapter/src/adapter/adapter_impl.rs b/crates/dbt-adapter/src/adapter/adapter_impl.rs index 3d6a338fe5f..cd84c439013 100644 --- a/crates/dbt-adapter/src/adapter/adapter_impl.rs +++ b/crates/dbt-adapter/src/adapter/adapter_impl.rs @@ -534,7 +534,7 @@ impl AdapterImpl { Bigquery => &[Append], Databricks => &[Append, Merge, InsertOverwrite, ReplaceWhere], Redshift => &[Append, DeleteInsert, Merge, Microbatch], - Fabric => &[Append, DeleteInsert, Merge, Microbatch], + Fabric | SqlServer => &[Append, DeleteInsert, Merge, Microbatch], Salesforce => &[Append, Merge], ClickHouse => &[Append, DeleteInsert, InsertOverwrite, Microbatch, Legacy], Spark => &[Append, Merge, InsertOverwrite, Microbatch], @@ -963,14 +963,14 @@ impl AdapterImpl { } Replay( adapter_type @ (Postgres | Redshift | Salesforce | DuckDB | Alt | Spark | Fabric - | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion - | Dremio | Oracle), + | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle), _, ) | Impl( adapter_type @ (Postgres | Redshift | Salesforce | DuckDB | Alt | Spark | Fabric - | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion - | Dremio | Oracle), + | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle), _, ) => Err(AdapterError::new( AdapterErrorKind::Internal, @@ -1001,8 +1001,8 @@ impl AdapterImpl { self.list_schemas_via_adbc(state, database) } Snowflake | Databricks | Redshift | Spark | DuckDB | Postgres | Salesforce | Fabric - | ClickHouse | Exasol | Athena | Starburst | Trino | Datafusion | Dremio | Oracle - | Alt | Bigquery => { + | SqlServer | ClickHouse | Exasol | Athena | Starburst | Trino | Datafusion + | Dremio | Oracle | Alt | Bigquery => { use crate::macro_exec::execute_macro_wrapper; use minijinja::value::{Kwargs, Value}; @@ -1105,7 +1105,7 @@ impl AdapterImpl { Postgres => "nspname", DuckDB => "schema_name", Alt => "schema_name", - Fabric => "schema", + Fabric | SqlServer => "schema", // https://github.com/ClickHouse/dbt-clickhouse/blob/main/dbt/include/clickhouse/macros/adapters.sql ClickHouse => "name", Exasol => "name", @@ -1388,8 +1388,8 @@ impl AdapterImpl { )]))) } Postgres | Bigquery | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { let err = format!( "describe_dynamic_table is not supported by the {} adapter", adapter_type @@ -1806,14 +1806,13 @@ impl AdapterImpl { // NOTE: This is the default behavior. If said adapter type does not // have a get_columns_in_relation() macro, it will fail with a // "macro does not exist" error - Athena | ClickHouse | Datafusion | Dremio | DuckDB | Alt | Exasol | Fabric | Oracle - | Postgres | Redshift | Salesforce | Snowflake | Spark | Starburst | Trino => { - execute_macro( - state, - &[RelationObject::new(relation.to_owned()).into_value()], - "get_columns_in_relation", - ) - } + Athena | ClickHouse | Datafusion | Dremio | DuckDB | Alt | Exasol | Fabric + | SqlServer | Oracle | Postgres | Redshift | Salesforce | Snowflake | Spark + | Starburst | Trino => execute_macro( + state, + &[RelationObject::new(relation.to_owned()).into_value()], + "get_columns_in_relation", + ), }; macro_result @@ -2071,8 +2070,8 @@ impl AdapterImpl { } Impl( Snowflake | Databricks | Redshift | Salesforce | Postgres | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle, + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle, _, ) => { // downcast relation @@ -2122,7 +2121,8 @@ impl AdapterImpl { } Impl( Postgres | Bigquery | Databricks | Redshift | Spark | DuckDB | Alt | Fabric - | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio | Oracle, + | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion + | Dremio | Oracle, _, ) => { if quote_config.unwrap_or(true) { @@ -2324,9 +2324,9 @@ impl AdapterImpl { Ok(none_value()) } - Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | Fabric | DuckDB - | Alt | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | Fabric + | SqlServer | DuckDB | Alt | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -2341,8 +2341,8 @@ impl AdapterImpl { ) -> AdapterResult> { match self.adapter_type() { Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { let mut result = vec![]; for (_, column) in columns_map { let col_name = if column.quote.unwrap_or(false) { @@ -2535,6 +2535,14 @@ impl AdapterImpl { (Fabric, ForeignKey) => Enforced, (Fabric, Custom) => NotSupported, + // SqlServer + (SqlServer, Check) => Enforced, + (SqlServer, NotNull) => Enforced, + (SqlServer, Unique) => Enforced, + (SqlServer, PrimaryKey) => Enforced, + (SqlServer, ForeignKey) => Enforced, + (SqlServer, Custom) => NotSupported, + // Salesforce ( Salesforce | Spark | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion @@ -2645,7 +2653,7 @@ impl AdapterImpl { } match self.adapter_type() { - Postgres | Bigquery | DuckDB | Alt => { + Postgres | Bigquery | DuckDB | Alt | SqlServer => { let grantee_cols = record_batch.column_values::("grantee")?; let privilege_cols = record_batch.column_values::("privilege_type")?; @@ -2869,8 +2877,8 @@ impl AdapterImpl { Ok(AgateTable::from_record_batch(Arc::new(catalog))) } Snowflake | Bigquery | Databricks | Spark | DuckDB | Alt | Postgres | Salesforce - | Fabric | ClickHouse | Exasol | Athena | Starburst | Trino | Datafusion | Dremio - | Oracle => Err(AdapterError::new( + | Fabric | SqlServer | ClickHouse | Exasol | Athena | Starburst | Trino + | Datafusion | Dremio | Oracle => Err(AdapterError::new( AdapterErrorKind::NotSupported, "build_catalog_from_show_tables_and_svv_columns is only supported for Redshift", )), @@ -2885,8 +2893,8 @@ impl AdapterImpl { match self.adapter_type() { Bigquery => nest_column_data_types(columns, constraints), Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -2924,8 +2932,8 @@ impl AdapterImpl { match self.adapter_type() { Bigquery => Ok(Value::from(render_struct_projection(col_name, data_type))), Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3022,8 +3030,8 @@ impl AdapterImpl { Ok(none_value()) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3076,8 +3084,8 @@ impl AdapterImpl { Self::parse_dataset_location(&batch) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3134,8 +3142,8 @@ impl AdapterImpl { Ok(none_value()) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3211,7 +3219,8 @@ impl AdapterImpl { } Salesforce => todo!("load_dataframe() for the Salesforce adapter"), Postgres | Snowflake | Databricks | Redshift | Spark | DuckDB | Alt | Fabric - | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio | Oracle => { + | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion + | Dremio | Oracle => { unimplemented!("only available with BigQuery or Salesforce adapter") } } @@ -3272,8 +3281,8 @@ impl AdapterImpl { Ok(none_value()) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3421,8 +3430,8 @@ impl AdapterImpl { } Impl( adapter_type @ (Snowflake | Bigquery | Databricks | Salesforce | Spark | Fabric - | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle), + | SqlServer | Exasol | Starburst | Athena | Trino | Datafusion + | Dremio | Oracle), _, ) => { unimplemented!( @@ -3494,8 +3503,8 @@ impl AdapterImpl { } } adapter_type @ (Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark - | DuckDB | Alt | Fabric | ClickHouse | Exasol | Starburst | Athena - | Trino | Datafusion | Dremio | Oracle) => { + | DuckDB | Alt | Fabric | SqlServer | ClickHouse | Exasol + | Starburst | Athena | Trino | Datafusion | Dremio | Oracle) => { unimplemented!( "is_replaceable is only available with BigQuery adapter, not {}", adapter_type @@ -3559,8 +3568,8 @@ impl AdapterImpl { Ok(Value::from_object(validated_config)) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3583,8 +3592,8 @@ impl AdapterImpl { adapter_type, ), Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3607,8 +3616,8 @@ impl AdapterImpl { ), ), Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3634,8 +3643,8 @@ impl AdapterImpl { Ok(Value::from_serialize(options)) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => Err(minijinja::Error::new( + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => Err(minijinja::Error::new( minijinja::ErrorKind::InvalidOperation, "get_common_options is only available with BigQuery adapter", )), @@ -3676,8 +3685,8 @@ impl AdapterImpl { Ok(Value::from(result)) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -3863,8 +3872,8 @@ impl AdapterImpl { Ok(Value::from(result)) } Postgres | Snowflake | Bigquery | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with Databricksadapter") } } @@ -4020,8 +4029,8 @@ impl AdapterImpl { } Postgres | Snowflake | Bigquery | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with Databricks adapter") } } @@ -4098,8 +4107,8 @@ impl AdapterImpl { Ok(()) } Postgres | Snowflake | Bigquery | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with Databricks adapter") } } @@ -4189,8 +4198,8 @@ impl AdapterImpl { Ok(!use_managed_iceberg) } Postgres | Snowflake | Bigquery | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with Databricks adapter") } } @@ -4531,8 +4540,8 @@ impl AdapterImpl { Ok(()) } Postgres | Snowflake | Databricks | Redshift | Salesforce | Spark | DuckDB | Alt - | Fabric | ClickHouse | Exasol | Starburst | Athena | Trino | Datafusion | Dremio - | Oracle => { + | Fabric | SqlServer | ClickHouse | Exasol | Starburst | Athena | Trino + | Datafusion | Dremio | Oracle => { unimplemented!("only available with BigQuery adapter") } } @@ -4911,8 +4920,8 @@ pub(crate) fn adapter_specific_behavior_flags(adapter_type: AdapterType) -> Vec< ); vec![skip_autocommit_transaction_statements, grants_extended] } - Postgres | Salesforce | Spark | DuckDB | Alt | ClickHouse | Exasol | Starburst | Athena - | Trino | Datafusion | Dremio | Oracle => vec![], + Postgres | Salesforce | Spark | DuckDB | Alt | SqlServer | ClickHouse | Exasol + | Starburst | Athena | Trino | Datafusion | Dremio | Oracle => vec![], } }