Skip to content

SNOW-2503709: visit_truediv_binary does not have backward compatibility #618

@cemsozens

Description

@cemsozens
  1. What version of Python are you using?

    Python 3.13.1 (main, Dec 3 2024, 17:59:52) [Clang 16.0.0 (clang-1600.0.26.4)]

  2. What operating system and processor architecture are you using?

    macOS-26.0.1-arm64-arm-64bit-Mach-O

  3. What are the component versions in the environment (pip freeze)?

    aiohappyeyeballs==2.4.3
    aiohttp==3.10.10
    aiokafka==0.12.0
    aiolimiter==1.2.1
    aiosignal==1.3.1
    alembic==1.16.1
    amqp==5.2.0
    annotated-types==0.7.0
    anyio==4.6.2.post1
    argcomplete==3.6.2
    asgiref==3.8.1
    asn1crypto==1.5.1
    async-timeout==4.0.3
    asyncache==0.3.1
    asynch==0.2.4
    asyncpg==0.29.0
    attrs==24.2.0
    billiard==4.2.1
    black==25.1.0
    boto3==1.40.56
    boto3-stubs==1.40.56
    botocore==1.40.56
    botocore-stubs==1.35.41
    cachetools==5.5.2
    celery==5.5.3
    celery-types==0.23.0
    certifi==2024.8.30
    cffi==1.17.1
    cfgv==3.4.0
    charset-normalizer==3.4.0
    ciso8601==2.3.1
    click==8.2.1
    click-didyoumean==0.3.1
    click-plugins==1.1.1
    click-repl==0.3.0
    clickhouse-driver==0.2.9
    clickhouse-sqlalchemy==0.3.2
    cloudflare==4.3.1
    coverage==7.10.7
    cramjam==2.11.0
    cryptography==43.0.3
    curlify==2.2.1
    datamodel-code-generator==0.31.2
    distlib==0.3.9
    distro==1.9.0
    dnspython==2.7.0
    ecdsa==0.19.1
    email-validator==2.2.0
    et-xmlfile==2.0.0
    events==0.5
    facebook-business==24.0.0
    faker==37.4.2
    fal-client==0.7.0
    fastapi==0.118.3
    filelock==3.16.1
    findimports==2.6.0
    frozenlist==1.4.1
    genson==1.3.0
    google-ads==28.0.0
    google-api-core==2.21.0
    google-api-python-client==2.178.0
    google-auth==2.29.0
    google-auth-httplib2==0.2.0
    google-auth-oauthlib==1.2.1
    googleapis-common-protos==1.65.0
    greenlet==3.1.1
    grpcio==1.67.0
    grpcio-status==1.62.3
    h11==0.14.0
    httpcore==1.0.6
    httplib2==0.22.0
    httptools==0.6.4
    httpx==0.28.1
    httpx-sse==0.4.1
    identify==2.6.1
    idna==3.10
    importlib-metadata==8.4.0
    inflect==7.5.0
    iniconfig==2.0.0
    iso4217==1.13.20250512
    isort==6.0.1
    jaraco-classes==3.4.0
    jaraco-context==6.0.1
    jaraco-functools==4.1.0
    jinja2==3.1.6
    jmespath==1.0.1
    joserfc==1.4.0
    json-logging==1.5.1
    jsonschema==4.25.1
    jsonschema-specifications==2024.10.1
    keyring==25.4.1
    kombu==5.5.3
    leb128==1.0.8
    lz4==4.3.3
    mako==1.3.5
    markupsafe==3.0.1
    more-itertools==10.5.0
    multidict==6.1.0
    mypy==1.18.2
    mypy-boto3-s3==1.40.0
    mypy-extensions==1.0.0
    nats-py==2.11.0
    networkx==3.5
    nkeys==0.2.1
    nodeenv==1.9.1
    numpy==2.3.2
    oauthlib==3.2.2
    openpyxl==3.1.5
    opensearch-py==3.0.0
    opentelemetry-api==1.38.0
    opentelemetry-exporter-otlp-proto-common==1.38.0
    opentelemetry-exporter-otlp-proto-grpc==1.38.0
    opentelemetry-instrumentation==0.59b0
    opentelemetry-instrumentation-asgi==0.59b0
    opentelemetry-proto==1.38.0
    opentelemetry-sdk==1.38.0
    opentelemetry-semantic-conventions==0.59b0
    opentelemetry-test-utils==0.59b0
    opentelemetry-util-http==0.59b0
    packaging==24.1
    pandas==2.3.1
    pandas-stubs==2.3.0.250703
    pandera==0.25.0
    pathspec==0.12.1
    permify==0.0.1
    platformdirs==4.3.6
    pluggy==1.5.0
    pre-commit==4.2.0
    prompt-toolkit==3.0.48
    propcache==0.2.0
    proto-plus==1.24.0
    protobuf==5.29.5
    pyarrow==17.0.0
    pyasn1==0.6.1
    pyasn1-modules==0.4.1
    pybars3==0.9.7
    pycountry==24.6.1
    pycparser==2.22
    pydantic==2.11.9
    pydantic-core==2.33.2
    pydantic-settings==2.11.0
    pygments==2.19.1
    pyhumps==3.8.0
    pyjwt==2.10.1
    pymeta3==0.5.1
    pynacl==1.5.0
    pyopenssl==24.2.1
    pyparsing==3.2.0
    pytest==8.4.1
    pytest-asyncio==1.2.0
    pytest-cov==7.0.0
    pytest-github-actions-annotate-failures==0.3.0
    pytest-random-order==1.2.0
    pytest-recording==0.13.4
    python-dateutil==2.9.0.post0
    python-dotenv==1.0.1
    python-http-client==3.3.7
    python-multipart==0.0.20
    pytz==2024.2
    pyyaml==6.0.2
    referencing==0.35.1
    requests==2.32.4
    requests-oauthlib==2.0.0
    rpds-py==0.22.3
    rsa==4.9
    ruff==0.13.0
    s3transfer==0.14.0
    sendgrid==6.12.4
    sentry-sdk==2.41.0
    six==1.16.0
    sniffio==1.3.1
    snowflake-connector-python==3.18.0
    snowflake-sqlalchemy==1.7.7
    sortedcontainers==2.4.0
    sqids==0.5.2
    sqlalchemy==2.0.43
    starlette==0.45.3
    stripe==12.3.0
    tomlkit==0.13.2
    typeguard==4.3.0
    types-awscrt==0.22.0
    types-cachetools==5.5.0.20240820
    types-jsonschema==4.25.1.20250822
    types-networkx==3.5.0.20250809
    types-openpyxl==3.1.5.20250809
    types-protobuf==5.27.0.20240626
    types-python-dateutil==2.9.0.20250809
    types-pytz==2024.2.0.20241003
    types-pyyaml==6.0.12.20250809
    types-requests==2.32.4.20250809
    types-s3transfer==0.10.3
    typing-extensions==4.12.2
    typing-inspect==0.9.0
    typing-inspection==0.4.0
    typos==1.35.1
    tzdata==2025.2
    tzlocal==5.2
    uritemplate==4.1.1
    urllib3==2.0.7
    uuid-utils==0.11.0
    uvicorn==0.35.0
    uvloop==0.21.0
    vcrpy==7.0.0
    vine==5.1.0
    virtualenv==20.26.6
    watchfiles==0.24.0
    wcwidth==0.2.13
    websockets==13.1
    werkzeug==3.1.3
    wrapt==1.16.0
    yarl==1.15.3
    zipp==3.20.2
    zstd==1.5.5.1
    
  4. What did you do?

    I have a query where i use division using / operant and the SnowflakeDialect has the default value of true for force_div_is_floordiv. The new visit_truediv_binary function gives warning that the behavior will change in the future releases and overrides SQLCompiler visit_truediv_binary` but runs

return (
                self.process(binary.left, **kw)
                + " / "
                + self.process(binary.right, **kw)
            )

which should run when div_is_floordiv is false.
5. What did you expect to see?

I expected that snwoflakecompiler to run

return (
                self.process(binary.left, **kw)
                + " / "
                # TODO: would need a fast cast again here,
                # unless we want to use an implicit cast like "+ 0.0"
                + self.process(
                    elements.Cast(
                        binary.right,
                        (
                            binary.right.type
                            if binary.right.type._type_affinity
                            is sqltypes.Numeric
                            else sqltypes.Numeric()
                        ),
                    ),
                    **kw,
                )
            )

along with the warning which is the old behaviour and keeps the changes backward compatible. This is what SQLCompiler runs when div_is_floordiv set as true. When it is set to false then it runs:
return ( self.process(binary.left, **kw) + " / " + self.process(binary.right, **kw) )
This function is introduced in b9b26e5
6. Can you set logging to DEBUG and collect the logs?

I don't think logs will help here as i don't get an error besides the warning which is:
div_is_floordiv value will be changed to False in a future release. This will generate a behavior change on true and floor division. Please review https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html#python-division-operator-performs-true-division-for-all-backends-added-floor-division

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions