Skip to content

Add tuple support for IN #12

@ivanharvard

Description

@ivanharvard

Thanks ChatGPT!!!

To support syntax like:

(a, b).IN(...)

you’ll need to define a custom wrapper class that can represent a tuple of fields or expressions, and override its IN() method. Python’s built-in tuple won’t let you customize method resolution (like .IN(...)), so here’s how you can approach it:


Step 1: Define a TupleExpression class

class TupleExpression:
    def __init__(self, *elements):
        self.elements = elements  # list of Field, ColumnReference, Expression, etc.

    def IN(self, subquery_or_values):
        return Condition(self, "IN", subquery_or_values)

    def evaluate(self, db):
        # Return a list of evaluated tuples
        return [tuple(e.evaluate(db)) for e in self.elements]

Step 2: Provide a utility function or override __call__

You can make the tuple expression creation explicit:

TUPLE = lambda *args: TupleExpression(*args)

WHERE(TUPLE(emp.a, emp.b).IN(...))

Or, if you're comfortable overriding Python’s __getitem__ with a proxy object, you could do:

Query.db.TUPLE[emp.a, emp.b].IN(...)

But this is more complex and less idiomatic than using a helper like TUPLE(...).


Step 3: Modify Condition to support TupleExpression

Update the Condition class to allow left to be a TupleExpression and ensure evaluation logic accounts for that shape.


Summary

Python does not let you write (a, b).IN(...) directly with overridden behavior because (a, b) is a tuple and tuple has no .IN() method.

So you must wrap the tuple manually using:

WHERE(TUPLE(emp.a, emp.b).IN(...))

This is a clear, extensible pattern and allows proper evaluation of tuple comparisons (e.g., row-wise matching against subqueries or value sets).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions