Skip to content

COPY statements incorrectly classified as "Unknown" instead of "Copy" #161

@fspoljar

Description

@fspoljar

Summary

Snowflake COPY statements are misclassified as "Unknown" statement type, causing them to be rejected when sql_statement_permissions is configured with Copy: true and Unknown: false.

Expected Behavior

When executing a Snowflake COPY statement with Copy: true in permissions, the statement should be recognized as type "Copy" and allowed to execute.

Actual Behavior

The statement is classified as "Unknown" and rejected. Setting Unknown: true is required as a workaround.

Steps to Reproduce

  1. Configure tools_config.yaml with:

    sql_statement_permissions:
      - Copy: true
      - Unknown: false
  2. Execute a Snowflake COPY statement:

    COPY INTO @MY_STAGE.EXPORTS/sales_export.csv.gz
    FROM (
        SELECT * FROM MY_DATABASE.PUBLIC.ORDERS LIMIT 10
    )
    FILE_FORMAT = (TYPE = CSV COMPRESSION = GZIP)
    HEADER = TRUE
    OVERWRITE = TRUE
    MAX_FILE_SIZE = 52428800
    SINGLE = TRUE;
  3. Observe that the query is rejected

  4. Change config to Unknown: true — the query now executes (confirming misclassification)

Additional Context

The issue appears to be in mcp_server_snowflake/query_manager/tools.py where sqlglot.parse_one() is called without specifying dialect="snowflake". This causes the parser to fail on Snowflake-specific syntax.

Verification script:

import sqlglot

COPY_QUERY = """COPY INTO @MY_STAGE.EXPORTS/sales_export.csv.gz
FROM (SELECT * FROM MY_DATABASE.PUBLIC.ORDERS LIMIT 10)
FILE_FORMAT = (TYPE = CSV COMPRESSION = GZIP) HEADER = TRUE OVERWRITE = TRUE
MAX_FILE_SIZE = 52428800 SINGLE = TRUE;"""

# Without dialect - raises ParseError
try:
    result = sqlglot.parse_one(COPY_QUERY)
except sqlglot.errors.ParseError:
    print("Classified as: Unknown")

# With Snowflake dialect - parses correctly
result = sqlglot.parse_one(COPY_QUERY, dialect="snowflake")
print(f"Classified as: {type(result).__name__}")  # Prints "Copy"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions