AltimateAI / vscode-dbt-power-user

This extension makes vscode seamlessly work with dbt™: Auto-complete, preview, column lineage, AI docs generation, health checks, cost estimation etc
https://www.altimate.ai
MIT License
427 stars 84 forks source link

Incorrect Compile Code from DBT Power User #1154

Open ashutran opened 1 month ago

ashutran commented 1 month ago

Expected behavior

While using the Complied DBT preview feature result is not as expected:

  1. In my model, I'm using a macro for the incremental logic, which contains various if-else statements to determine the compiled code. However, it seems that part of the logic is being skipped, and I'm not sure why this is happening.

image image 2024-05-21 20_31_45-dim_incremental_merge_by_pk sql - dmg-gcp-cdw-data-etl - Visual Studio Code

  1. I compared the compiled code generated by DBT with the code generated by the plugin, and I noticed that several pieces of logic that should be present in the compiled code are missing.

2024-05-21 19_31_32-srv_temp____temp__dim-appraisal_pps_t sql - dmg-gcp-cdw-data-etl - Visual Studio

  1. In my model, after implementing the incremental logic, I use another macro to apply the casting logic to ensure each column is cast to its appropriate type. However, this step is failing.

2024-05-22 12_33_51-

  1. While executing the query, it's failing with the following error. My DBT architecture places all models under a folder called CDW. However, using dbt deps, we're downloading the project dependencies into a core folder, as specified in the packages.yml file.

{ "code": -1, "message": "Database Error\n Syntax error: SELECT list must not be empty at [305:1]", "data": "\"Error: Database Error\n Syntax error: SELECT list must not be empty at [305:1]\n\tat DBTCoreProjectIntegration_1. (c:\\Users\\.vscode\\extensions\\innoverio.vscode-dbt-power-user-0.39.12\\dist\\extension.js:18398:127)\n\tat Generator.throw ()\n\tat rejected (c:\\Users\\.vscode\\extensions\\innoverio.vscode-dbt-power-user-0.39.12\\dist\\extension.js:25808:28)\"" } 2024-05-22 12_38_24-

image

Actual behavior

After compiling the code

  1. It should read the macro logic and based on that it should return the correct code.
  2. Should apply the casting logic as mentioned the model using the specific Macro.
  3. Query Result should return the value

    Steps To Reproduce

    Using poetry shell to activate the poetry virtual env Using python version 3.11.6 dbt-core 1.6.1 dbt-bigquery 1.6.4

Create any model having Macro for incremental logic using if-else where it'll check if the table exist then if condition else another condition image image

Log output/Screenshots

No response

Operating System

Windows 10

dbt version

1.6.1

dbt Adapter

dbt-bigquery 1.6.4

dbt Power User version

v0.39.12

Are you willing to submit PR?

sweep-ai[bot] commented 1 month ago

🚀 Here's the PR! #1159

💎 Sweep Pro: You have unlimited Sweep issues

Actions

Relevant files (click to expand). Mentioned files will always appear here. https://github.com/AltimateAI/vscode-dbt-power-user/blob/76cd20da0218230f0d18d18ac79986087558215e/dbt_core_integration.py#L1-L825 https://github.com/AltimateAI/vscode-dbt-power-user/blob/76cd20da0218230f0d18d18ac79986087558215e/src/dbt_client/dbtCoreIntegration.ts#L1-L1089 https://github.com/AltimateAI/vscode-dbt-power-user/blob/76cd20da0218230f0d18d18ac79986087558215e/altimate_packages/altimate/utils.py#L1-L350 https://github.com/AltimateAI/vscode-dbt-power-user/blob/76cd20da0218230f0d18d18ac79986087558215e/altimate_packages/sqlglot/generator.py#L1-L2731

Step 2: ⌨️ Coding

dbt_core_integration.py

Add debugging statements to the `_compile_node` method to log the progress of the incremental logic macro execution.
--- 
+++ 
@@ -13,6 +13,21 @@
             else:
                 # this is essentially a convenient wrapper to adapter.get_compiler
                 compiled_node = self.sql_compiler.compile(self.dbt)
+
+            # Add debugging statements
+            self.dbtTerminal.debug(
+                "_compile_node",
+                f"Compiling node: {node.unique_id}",
+            )
+            self.dbtTerminal.debug(
+                "_compile_node",
+                f"Raw SQL: {getattr(compiled_node, RAW_CODE)}",
+            )
+            self.dbtTerminal.debug(
+                "_compile_node",
+                f"Compiled SQL: {getattr(compiled_node, COMPILED_CODE)}",
+            )
+
             return DbtAdapterCompilationResult(
                 getattr(compiled_node, RAW_CODE),
                 getattr(compiled_node, COMPILED_CODE),

dbt_core_integration.py

Verify that the `sql_compiler` is properly set up and configured to handle macros with if-else statements.
--- 
+++ 
@@ -7,4 +7,13 @@
             self._sql_compiler = SqlCompileRunner(
                 self.config, self.adapter, node=None, node_index=1, num_nodes=1
             )
+
+            # Verify sql_compiler configuration
+            assert self._sql_compiler.config.has_option("compile", "handle_macros"), (
+                "sql_compiler configuration missing 'handle_macros' option"
+            )
+            assert self._sql_compiler.config.get("compile", "handle_macros"), (
+                "sql_compiler not configured to handle macros"
+            )
+
         return self._sql_compiler

dbt_core_integration.py

Ensure that the `compile` method of the `sql_compiler` is being called with the correct arguments, including the dbt manifest.
--- 
+++ 
@@ -12,7 +12,7 @@
                 )
             else:
                 # this is essentially a convenient wrapper to adapter.get_compiler
-                compiled_node = self.sql_compiler.compile(self.dbt)
+                compiled_node = self.sql_compiler.compile(manifest=self.dbt)
             return DbtAdapterCompilationResult(
                 getattr(compiled_node, RAW_CODE),
                 getattr(compiled_node, COMPILED_CODE),

dbt_core_integration.py

Add logging statements in the `_compile_node` method to capture the compiled code generated by dbt and the plugin.
--- 
+++ 
@@ -13,10 +13,25 @@
             else:
                 # this is essentially a convenient wrapper to adapter.get_compiler
                 compiled_node = self.sql_compiler.compile(self.dbt)
-            return DbtAdapterCompilationResult(
+
+            # Log compiled code
+            self.dbtTerminal.debug(
+                "_compile_node",
+                f"DBT compiled code: {getattr(compiled_node, COMPILED_CODE)}",
+            )
+
+            result = DbtAdapterCompilationResult(
                 getattr(compiled_node, RAW_CODE),
                 getattr(compiled_node, COMPILED_CODE),
                 compiled_node,
             )
+
+            # Log plugin compiled code
+            self.dbtTerminal.debug(
+                "_compile_node",
+                f"Plugin compiled code: {result.compiled_sql}",
+            )
+
+            return result
         except Exception as e:
             raise Exception(str(e))

Step 3: 🔄️ Validating

Your changes have been successfully made to the branch sweep/incorrect_compile_code_from_dbt_power_us. I have validated these changes using a syntax checker and a linter.


[!TIP] To recreate the pull request, edit the issue title or description.

This is an automated message generated by Sweep AI.