typedb-driver icon indicating copy to clipboard operation
typedb-driver copied to clipboard

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

Open izmalk opened this issue 1 year ago • 3 comments

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;
  1. 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 <lambda>
    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 <module>
    "$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))
  1. 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.

izmalk avatar Feb 12 '24 17:02 izmalk

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).

krishnangovindraj avatar Feb 12 '24 17:02 krishnangovindraj

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 avatar Feb 12 '24 17:02 izmalk

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';" }] })

izmalk avatar Feb 12 '24 18:02 izmalk