codeant-ai-for-open-source[bot] commented on code in PR #42095:
URL: https://github.com/apache/superset/pull/42095#discussion_r3591317742


##########
superset/db_engine_specs/postgres.py:
##########
@@ -49,6 +52,40 @@
 
 logger = logging.getLogger()
 
+_DATE_TRUNC_UNITS: frozenset[str] = frozenset(
+    {"second", "minute", "hour", "day", "week", "month", "quarter", "year"}
+)
+
+
+def normalize_date_trunc_units(expression: str) -> str:
+    """Lowercase recognized DATE_TRUNC unit literals without regenerating 
SQL."""
+    try:
+        tokens = Tokenizer(dialect="postgres").tokenize(expression)
+    except TokenError:
+        return expression
+
+    replacements: list[tuple[int, int, str]] = []
+    for index, (function, left_paren, unit) in enumerate(
+        zip(tokens, tokens[1:], tokens[2:], strict=False)
+    ):
+        normalized_unit = unit.text.lower()
+        raw_literal = expression[unit.start : unit.end + 1]
+        if (
+            function.token_type is TokenType.VAR
+            and function.text.upper() == "DATE_TRUNC"
+            and (index == 0 or tokens[index - 1].token_type is not 
TokenType.DOT)

Review Comment:
   **Suggestion:** The normalization logic skips any `DATE_TRUNC` call preceded 
by a dot, which also excludes valid PostgreSQL built-in calls like 
`pg_catalog.DATE_TRUNC(...)`. In those cases uppercase units remain unchanged, 
so metric SQL can still diverge from the generated time-grain expression and 
trigger grouping failures. Restrict the skip logic to non-built-in dotted names 
(or explicitly allow `pg_catalog.DATE_TRUNC`) so schema-qualified built-ins are 
normalized too. [incomplete implementation]
   
   <details>
   <summary><b>Severity Level:</b> Major ⚠️</summary>
   
   ```mdx
   - ❌ PostgreSQL charts with schema-qualified DATE_TRUNC metrics fail grouping.
   - ⚠️ Redshift metrics using pg_catalog.DATE_TRUNC risk similar failures.
   - ⚠️ Metric normalization inconsistent for equivalent DATE_TRUNC invocations.
   ```
   </details>
   <details>
   <summary><b>Steps of Reproduction ✅ </b></summary>
   
   ```mdx
   1. Define a SQL metric on a PostgreSQL dataset whose expression uses a 
schema-qualified
   built-in DATE_TRUNC, for example `pg_catalog.DATE_TRUNC('QUARTER', 
created_at)`, so that
   the metric path in `SqlMetric.get_sqla_col()` at
   `superset/connectors/sqla/models.py:1249-1252` will call
   `_normalize_custom_sql_metric(...)` with this expression and the Postgres 
engine spec
   normalizer.
   
   2. When the chart or explore query runs, `_normalize_custom_sql_metric()` in
   `superset/models/helpers.py:835-833` invokes
   `PostgresEngineSpec.normalize_custom_sql_metric()` (defined in
   `superset/db_engine_specs/postgres.py:316-318`), which forwards the metric 
SQL to
   `normalize_date_trunc_units()` at 
`superset/db_engine_specs/postgres.py:60-87`.
   
   3. Inside `normalize_date_trunc_units()`, the expression 
`pg_catalog.DATE_TRUNC('QUARTER',
   created_at)` is tokenized by sqlglot (lines 62-63), and the loop at lines 
68-70 iterates
   over `(function, left_paren, unit)` triples; for the triple corresponding to 
the
   DATE_TRUNC call, `function` is the `DATE_TRUNC` identifier but `index` is 2 
and
   `tokens[index - 1]` is the preceding `DOT` token, so the condition `and 
(index == 0 or
   tokens[index - 1].token_type is not TokenType.DOT)` at line 76 evaluates to 
False and no
   replacement is added.
   
   4. Because the schema-qualified built-in DATE_TRUNC call is skipped by this 
dotted-name
   guard, the unit literal remains `'QUARTER'` instead of being normalized to 
`'quarter',
   even though the engine's time-grain templates in
   `PostgresBaseEngineSpec._time_grain_expressions` (see
   `superset/db_engine_specs/postgres.py:211-226`) use unqualified 
`DATE_TRUNC('quarter',
   {col})`, so custom metrics written with `pg_catalog.DATE_TRUNC('QUARTER', 
...)` can still
   diverge from the generated grouping expression and reintroduce the grouping 
inconsistency
   that this normalization hook is meant to prevent.
   ```
   </details>
   
   [![Fix in 
Cursor](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-cursor-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=cursor&prompt_id=ec30d5ce2fa24e138689ffe20cba5fee&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
 [![Fix in VSCode 
Claude](https://new-codeant-butcket.s3.us-west-1.amazonaws.com/badges/fix-in-vscode-claude-flat.svg)](https://app.codeant.ai/fix-in-ide?tool=vscode-claude&prompt_id=ec30d5ce2fa24e138689ffe20cba5fee&service=github&base_url=https%3A%2F%2Fgithub.com&org=apache&repo=apache%2Fsuperset)
   
   *(Use Cmd/Ctrl + Click for best experience)*
   <details>
   <summary><b>Prompt for AI Agent 🤖 </b></summary>
   
   ```mdx
   This is a comment left during a code review.
   
   **Path:** superset/db_engine_specs/postgres.py
   **Line:** 76:76
   **Comment:**
        *Incomplete Implementation: The normalization logic skips any 
`DATE_TRUNC` call preceded by a dot, which also excludes valid PostgreSQL 
built-in calls like `pg_catalog.DATE_TRUNC(...)`. In those cases uppercase 
units remain unchanged, so metric SQL can still diverge from the generated 
time-grain expression and trigger grouping failures. Restrict the skip logic to 
non-built-in dotted names (or explicitly allow `pg_catalog.DATE_TRUNC`) so 
schema-qualified built-ins are normalized too.
   
   Validate the correctness of the flagged issue. If correct, How can I resolve 
this? If you propose a fix, implement it and please make it concise.
   Once fix is implemented, also check other comments on the same PR, and ask 
user if the user wants to fix the rest of the comments as well. if said yes, 
then fetch all the comments validate the correctness and implement a minimal fix
   ```
   </details>
   <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42095&comment_hash=ad24e62155fede6bd3c4969080bc0581f845e9eaf20072c9b1376b4e6bbb5c85&reaction=like'>👍</a>
 | <a 
href='https://app.codeant.ai/feedback?pr_url=https%3A%2F%2Fgithub.com%2Fapache%2Fsuperset%2Fpull%2F42095&comment_hash=ad24e62155fede6bd3c4969080bc0581f845e9eaf20072c9b1376b4e6bbb5c85&reaction=dislike'>👎</a>



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to