Skip to content

[Bug] transform_sql corrupts string literals containing the MDL catalog/schema prefix #2761

Closed

Description

@dafyy321-pixel

Describe the bug

SessionContext.transform_sql() removes the MDL catalog/schema prefix from string literals when the same text appears in a query.

For an MDL whose catalog is my_catalog and schema is my_schema, the transformer should remove my_catalog.my_schema. from generated table references. It currently removes every occurrence of that text from the serialized SQL, including values and patterns inside expressions.

No exception is raised. The returned SQL is valid, but its meaning has changed.

To reproduce

Reproduced with wren-core-py==0.8.0:

import base64
import json

from wren_core import SessionContext

manifest = {
    "catalog": "my_catalog",
    "schema": "my_schema",
    "models": [
        {
            "name": "customer",
            "tableReference": {
                "catalog": "",
                "schema": "",
                "table": "customer",
            },
            "columns": [
                {"name": "c_custkey", "type": "integer"},
                {"name": "c_name", "type": "varchar"},
            ],
            "primaryKey": "c_custkey",
        }
    ],
}

encoded_manifest = base64.b64encode(
    json.dumps(manifest).encode("utf-8")
).decode("utf-8")

ctx = SessionContext(encoded_manifest, None)

sql = """
SELECT
    'my_catalog.my_schema.keep' AS marker,
    CASE
        WHEN c_name LIKE 'my_catalog.my_schema.%'
        THEN 'my_catalog.my_schema.match'
        ELSE 'my_catalog.my_schema.miss'
    END AS category,
    c_custkey
FROM my_catalog.my_schema.customer
"""

print(ctx.transform_sql(sql))

Actual output:

SELECT 'keep' AS marker, CASE WHEN customer.c_name LIKE '%' THEN 'match' ELSE 'miss' END AS "category", customer.c_custkey FROM (SELECT customer.c_custkey, customer.c_name FROM (SELECT __source.c_custkey AS c_custkey, __source.c_name AS c_name FROM customer AS __source) AS customer) AS customer

The table qualifier was removed as intended, but these values were also changed:

'my_catalog.my_schema.keep'  -> 'keep'
'my_catalog.my_schema.%'     -> '%'
'my_catalog.my_schema.match' -> 'match'
'my_catalog.my_schema.miss'  -> 'miss'

Expected behavior

Catalog and schema qualifiers should be removed only from table relations. String literals must keep their original contents, including literals used as selected values, LIKE patterns, and CASE results.

Why this happens

The public Python call reaches the affected code through this path:

SessionContext.transform_sql()
  -> core/wren-core-py/src/context.rs
  -> mdl::transform_sql_with_ctx()
  -> Unparser::plan_to_sql()
  -> Statement::to_string()
  -> String::replace("my_catalog.my_schema.", "")

The last replacement runs after the SQL AST has been serialized, so it cannot distinguish a table name from text inside an expression.

This can silently change query results. A label returned by SELECT or CASE is shortened, and a LIKE predicate may match a different set of rows.

The qualifier should instead be removed from relation ObjectName nodes before the AST is rendered back to SQL.

Duplicate check

Searched open Issues and PRs for transform_sql, catalog schema, string literal, and the exact qualifier-removal behavior on September 24, 2026.

Issues #2745 and #2746 cover different SQL transformation failures. Draft PR #2551 touches core/src/mdl/mod.rs, but it does not change the qualifier-removal code or the affected lines. No matching Issue, PR, assignee, or active claim was found.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions