typedb / typedb-driver

TypeDB Drivers for Rust, Python, Java, Node.js, C, C++, and C#.
https://typedb.com
Apache License 2.0
38 stars 32 forks source link

Python driver's put_rule() method has unexpected arguments syntax #596

Open izmalk opened 8 months ago

izmalk commented 8 months ago

Description

The put_rule() method takes three arguments: the rule's label, condition, and conclusion. All three are strings. For some reason, the condition must be enveloped in curly brackets, and a conclusion must be without a tailing semicolon.

Environment

  1. TypeDB distribution: Core
  2. TypeDB version: 2.26.6-rc1
  3. Environment: Mac
  4. Studio version: -
  5. Other details:typedb-driver 2.26.6-rc1

Reproducible Steps

  1. Set up

    define
    email sub attribute,
    value string;
    name sub attribute,
    value string;
    tag sub attribute,
    value string;
    friendship sub relation,
    relates friend;
    user sub entity,
    owns email @key,
    owns name,
    owns tag,
    plays friendship:friend;
  2. Execute

with driver.session(DB_NAME, SessionType.SCHEMA) as session:
        with session.transaction(TransactionType.WRITE) as transaction:
            rules = transaction.logic.get_rules()
            for rule in rules:
                print("Rule label:", rule.label)
                print("  Condition:", rule.when)
                print("  Conclusion:", rule.then)
            new_rule = transaction.logic.put_rule("Employee",
                                                  "$u isa user, has email $e; $e contains '@vaticle.com';",
                                                  "$u has name 'Employee';").resolve()
            if new_rule == transaction.logic.get_rule("Employee").resolve():
                print("New rule has been found.")
            print(new_rule.then, new_rule.when)

            new_rule.delete(transaction).resolve()

            if transaction.logic.get_rule("Employee").resolve() is None:
                print("New rule has been deleted.")

            print(new_rule.when)
            print(new_rule.is_deleted(transaction).resolve())
            transaction.commit()
  1. Unexpected result

It produces the following error if no curly brackets around Condition or the tailing semicolon in the Conclusion are present:

See error ``` Traceback (most recent call last): File "/Users/vladimir/Documents/GitHub/python_features_code_test/venv/lib/python3.11/site-packages/typedb/common/promise.py", line 66, in resolve return self.inner() ^^^^^^^^^^^^ File "/Users/vladimir/Documents/GitHub/python_features_code_test/venv/lib/python3.11/site-packages/typedb/common/promise.py", line 46, in inner if _res := raw(): ^^^^^ File "/Users/vladimir/Documents/GitHub/python_features_code_test/venv/lib/python3.11/site-packages/typedb/logic/logic_manager.py", line 70, in return Promise.map(_Rule, lambda: rule_promise_resolve(promise)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/vladimir/Documents/GitHub/python_features_code_test/venv/lib/python3.11/site-packages/typedb/native_driver_wrapper.py", line 1168, in rule_promise_resolve return native_driver_python.rule_promise_resolve(promise) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ native_driver_python.TypeDBDriverExceptionNative: [TQL03] TypeQL Error: There is a syntax error near line 1: --> $u isa user, has email $e; $e contains '@vaticle.com'; During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/vladimir/Documents/GitHub/typedb_python_driver_manual/main.py", line 199, in "$u has name 'Employee';").resolve() ^^^^^^^^^ File "/Users/vladimir/Documents/GitHub/python_features_code_test/venv/lib/python3.11/site-packages/typedb/common/promise.py", line 68, in resolve raise TypeDBDriverException.of(e) typedb.common.exception.TypeDBDriverException: [TQL03] TypeQL Error: There is a syntax error near line 1: --> $u isa user, has email $e; $e contains '@vaticle.com'; ```

Expected result

I think it should work with a valid TypeQL string: no curly brackets are required (other than for a Disjunction/Negation) in Condition, and a tailing semicolon should be mandatory at the end of the Conclusion.

Additional information

  1. Krishnan suggested the fix by replacing transaction.logic with transaction.native_object in rule.py line 72:
    def delete(self, transaction: _Transaction) -> Promise[None]:
        promise = rule_delete(transaction.native_object, self.native_object)
        return Promise(lambda: void_promise_resolve(promise))
  2. Joshua notified us that there is a bug with deleted rules - they can stay cached while we stay in the same transaction where the rule got deleted.
krishnangovindraj commented 8 months ago

The exception here says nothing about the syntax expected. Could you re-run it with the transaction.logic -> transaction.native_object rename and post the syntax error (if it happens).

izmalk commented 8 months ago

The exception here says nothing about the syntax expected. Could you re-run it with the transaction.logic -> transaction.native_object rename and post the syntax error (if it happens).

Thanks for noticing, I updated the error for the correct one.

izmalk commented 8 months ago

I tried the same approach with Rust driver and got the following error:

Error: TypeQL(Error { errors: [TypeQLError::SyntaxErrorDetailed { message: "[TQL03] TypeQL Error: There is a syntax error near line 1:\n--> $u isa user, has email $e; $e contains '@vaticle.com';", error_line_nr: 1, formatted_error: "--> $u isa user, has email $e; $e contains '@vaticle.com';" }] })