EvgSkv / logica

Logica is a logic programming language that compiles to SQL. It runs on Google BigQuery, PostgreSQL and SQLite.

Home Page:https://logica.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CamelCase weirdness

craigpastro opened this issue Β· comments

πŸ‘‹ Hello! I'm having great fun playing around with Logica. Thanks for the project.

I run into something a bit strange and was wondering if it is a bug.

I have a fact and rule like so:

Tuple(namespace: "document", id: "1", rel: "writer", user: "id", userId: "badger", user_namespace: "", user_object_id: "");

List(namespace:, id:, rel:, user:, userId:, user_namespace:, user_object_id:) :-
    Tuple(namespace:, id:, rel:, user:, userId:, user_namespace:, user_object_id:);

and if I try to run this as is, it returns a parsing error:

Parsing:
List(namespace:, id:, rel:, user:, userId:, user_namespace:, user_object_id:) :-
    Tuple(namespace:, id:, rel:, user:, userId:, user_namespace:, user_object_id:)

[ Error ] Could not parse expression of a value.

If I parametrize userId (with an x) as in the following:

Tuple(namespace: "document", id: "1", rel: "writer", user: "id", userId: "badger", user_namespace: "", user_object_id: "");

List(namespace:, id:, rel:, user:, userId: x, user_namespace:, user_object_id:) :-
    Tuple(namespace:, id:, rel:, user:, userId: x, user_namespace:, user_object_id:);

then it works fine:

(env) $ logica zanzibar.l run List
+-----------+----+--------+--------+----------+----------------+----------------+
| namespace | id | rel    | user   | userId   | user_namespace | user_object_id |
+-----------+----+--------+--------+----------+----------------+----------------+
| document  | 1  | writer | id     | badger   |                |                |
+-----------+----+--------+--------+----------+----------------+----------------+

Similarly, if I don't parametrize, but use snake case user_id then it also works fine.

So, should I always just stick with snake_case?

Thanks for any insights πŸ™Œ

Hello again! I found one more thing. Sorry, I tried to make a smaller example than below, but for some reason I could not reproduce the behaviour in a much smaller example.

Again, it comes down to a problem with various cases.

I have the following data:

Config(namespace: "document", rel: "viewer", rewrite: "tupleToUserset", relation: "parent");
Tuple(namespace: "document", id: "1", rel: "parent", user: "folder", user_id: "x");
Tuple(namespace: "folder", id: "x", rel: "parent", user: "id", user_id: "");

List(namespace:, id:, rel:, user:, user_id:) :-
    Tuple(namespace:, id:, rel:, user:, user_id:);
    
List(namespace:, id:, rel:, user:, user_id:) :-
    Config(namespace:, rel:, rewrite: "tupleToUserset", relation: tupleset),
    Tuple(namespace:, id:, rel: tupleset, user: folder, user_id: x),
    List(namespace: folder, id: x, rel: tupleset, user:, user_id:);

The problem is with the user_id field mapping to the id field with x in the last two lines. In the above case, if I run List, I get three results as expected:

+-----------+----+--------+--------+---------+
| namespace | id | rel    | user   | user_id |
+-----------+----+--------+--------+---------+
| document  | 1  | viewer | id     |         |
| document  | 1  | parent | folder | x       |
| folder    | x  | parent | id     |         |
+-----------+----+--------+--------+---------+

However, if I replace x with user_id then I only get two results!

+-----------+----+--------+--------+---------+
| namespace | id | rel    | user   | user_id |
+-----------+----+--------+--------+---------+
| document  | 1  | parent | folder | x       |
| folder    | x  | parent | id     |         |
+-----------+----+--------+--------+---------+

If I replace x with userId, then I get a parse error.

Is this a bug? For the moment I think the safest way is to use all lowercase names and variables. Is that well-known? Sorry if I missed something in the documentation.

Thanks!

Oh, this is all with the SQLite backend.

Hi @craigpastro πŸ‘‹

For the first problem: the issue is that (as you have correctly inferred) variables must be lowercase. It's not enforced for fields, thus resulting in the puzzling error message when the field is attempted to be parsed as a variable as well. I should make documentation and and error message more clear.

For the second problem: so far it seems to me that it is calculated as intended and your second rule produces no rows. Can it be the case? Or please print the exact code that produces puzzling result (to make sure I debug exactly what you have in mind), and I'll be happy to take a look.

Hello @EvgSkv πŸ‘‹ Thanks for taking the time to answer! I'll remember that variables must be lowercase.

As for the second problem, I think it was my mistake because I was trying to the same name as a field name and a variable name. That is, user_id in the following is probably not correct because of the last user_id: field in the last line.

... :-
    Tuple(namespace:, id:, rel: tupleset, user: folder, user_id: user_id),
    List(namespace: folder, id: user_id, rel: tupleset, user:, user_id:);

Thanks again!

Glad I could help! :-) Please don't hesitate to reach out if you have any further questions.

Thank you @EvgSkv πŸ™Œ