ydb-platform / yoj-project

YDB ORM for Java (YOJ) is a lightweight ORM for immutable entities. It has native support for YDB and is battle-tested.
Apache License 2.0
13 stars 12 forks source link

Unexpected behaviour in query builder: using `where` after `and` #60

Closed lavrukov closed 7 months ago

lavrukov commented 7 months ago

I wrote this code and after it I spend an hour for detect a problem

    private TableQueryBuilder<Binding> getBindingsByTargetQuery(Binding.Type type, String target) {
        return db().BindingTable().query()
                .index(Binding.TYPE_TARGET_INDEX_NAME)
                .and("id.type").eq(type)
                .where("id.target").eq(target);
    }

The problem in where after and. This query will generate a filter WHERE id_target = "$my_target" without using id.type. This bug could be easy to get on copy-pasting.

It looks like this case should be uncompilable, or at least generate an exception.

nvamelichev commented 7 months ago

Making where() and and() do the same thing would be the easiest possible fix. You can then write, e.g.

return db().bindings().query()
    .where("id.type").eq(type)
    .where("id.target").eq(target)
    .index(...)
    .limit(...)
    .find();

But you can still do some moderately silly things, e.g. with or():

return db.myTable().query()
    .or("field1").eq(value1)    // just a funny way to express `WHERE field1=value1`
    .where("field2").eq(value2) // ...treated as `AND field2=value2`
    .find();

What do you think?

nvamelichev commented 7 months ago

@lavrukov Potential easy fix (making where() and and() mean the same thing): https://github.com/ydb-platform/yoj-project/pull/62