Repository: SuperDuperDB/superduperdb
File: superduperdb/backends/ibis/query.py (Python)

Code before:
                'output_id': str(ids[ix]),
                'input_id': str(ids[ix]),
                'query_id': query_id,
                'output': outputs[ix],
                'key': key,
            }
            table_records.append(d)

        for r in table_records:
            if isinstance(r['output'], dict) and '_content' in r['output']:
                r['output'] = r['output']['_content']['bytes']
        db.databackend.insert(f'_outputs/{model}/{version}', table_records)


class _LogicalExprMixin:
    def _logical_expr(self, members, collection, k, other: t.Optional[t.Any] = None):
        if other:
            args = [other]
        else:
            args = []
        members.append(
            IbisQueryComponent(k, args=args, kwargs={}, type=QueryType.QUERY)
        )
        return IbisQueryLinker(collection, members=members)

    def eq(self, other, members, collection):
        k = '__eq__'
        return self._logical_expr(members, collection, k, other=other)

    def or_(self, other, members, collection):
        k = '__or__'
        return self._logical_expr(members, collection, k, other=other)

    def not_(self, members, collection):
        k = '__not__'
        return self._logical_expr(members, collection, k)

    def and_(self, other, members, collection):
        k = '__and__'
        return self._logical_expr(members, collection, k, other=other)

    def gt(self, other, members, collection):
        k = '__gt__'
        return self._logical_expr(members, collection, k, other=other)

    def lt(self, other, members, collection):
        k = '__lt__'
        return self._logical_expr(members, collection, k, other=other)

    def getitem(self, other, members, collection):
        k = '__getitem__'

Review comment (suggestion):
If we don't do this, we will get an error when

```python
db.execute(table.select('id', 'x').add_fold('train')) 
```

Because we need to add '_fold' in parameters of `select`
Like this
```python
db.execute(table.select('id', 'x', '_fold').add_fold('train')) 
```

I guess users will get stuck here, as I was stuck here for a while.

Code after:
            d = {
                'output_id': str(ids[ix]),
                'input_id': str(ids[ix]),
                'query_id': query_id,
                'output': outputs[ix],
                'key': key,
            }
            table_records.append(d)

        for r in table_records:
            if isinstance(r['output'], dict) and '_content' in r['output']:
                r['output'] = r['output']['_content']['bytes']
        db.databackend.insert(f'_outputs/{model}/{version}', table_records)

    def add_fold(self, fold: str) -> Select:
        if self.query_linker is not None:
            # make sure we have a fold column in the query
            query_members = [
                i
                for i in self.query_linker.members
                if isinstance(i, IbisQueryComponent)
            ]
            if query_members:
                last_member = query_members[-1]
                if '_fold' not in last_member.args:
                    last_member.args = tuple(list(last_member.args) + ['_fold'])
        return self.filter(self._fold == fold)


class _LogicalExprMixin:
    def _logical_expr(self, members, collection, k, other: t.Optional[t.Any] = None):
        if other:
            args = [other]
        else:
            args = []
        members.append(
            IbisQueryComponent(k, args=args, kwargs={}, type=QueryType.QUERY)
        )
        return IbisQueryLinker(collection, members=members)

    def eq(self, other, members, collection):
        k = '__eq__'
        return self._logical_expr(members, collection, k, other=other)

    def or_(self, other, members, collection):
        k = '__or__'
        return self._logical_expr(members, collection, k, other=other)

    def not_(self, members, collection):
        k = '__not__'
        return self._logical_expr(members, collection, k)