Skip to content

sqlite3: exception from a collation callback is replaced by SystemError #161837

Open

Description

@grgalex

Bug report

Summary

When a collation callback raises, sqlite3 returns 0 to SQLite and leaves the exception pending. SQLite keeps evaluating the row, and a later failure in the same step (here abs() of the smallest 64-bit integer, an integer overflow) makes sqlite3 build its own OperationalError with the collation's exception still set. The interpreter reports this as a SystemError, and the original exception is lost.

Expected: the collation's exception should propagate, or at least chain as the cause.

Reproducer

import sqlite3

def coll(a, b):
    if a == "boom":
        raise KeyError("collation raised")
    return (a > b) - (a < b)

con = sqlite3.connect(":memory:")
con.create_collation("c", coll)
con.execute("create table t(x, y)")
con.executemany("insert into t values (?, ?)",
                [(1, "a"), (-9223372036854775808, "boom")])
cur = con.execute("select case when y = 'q' collate c then abs(x) else 0 end from t")
cur.fetchone()
KeyError: 'collation raised'

The above exception was the direct cause of the following exception:

SystemError: <class 'sqlite3.OperationalError'> returned a result with an exception set

CPython versions tested on:

CPython main branch

Operating systems tested on:

Linux

Linked PRs

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

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions