Skip to content
Snippets Groups Projects
Select Git revision
  • 7c6d25cb28ba860a01fc35ca4b4df69e7b73c5f9
  • main default protected
  • dev protected
  • f-fix-accent-sensitivity
  • f-filesystem-import
  • f-update-acl
  • f-filesystem-link
  • f-filesystem-directory
  • f-filesystem-core
  • f-filesystem-cleanup
  • f-string-ids
  • f-filesystem-main
  • f-multipart-encoding
  • f-trigger-advanced-user-tools
  • f-real-rename-test-pylibsolo2
  • f-real-rename-test-pylibsolo
  • f-real-rename-test
  • f-linkahead-rename
  • f-reference-record
  • f-xml-serialization
  • f-xfail-server-181
  • linkahead-pylib-v0.18.0
  • linkahead-control-v0.16.0
  • linkahead-pylib-v0.17.0
  • linkahead-mariadbbackend-v8.0.0
  • linkahead-server-v0.13.0
  • caosdb-pylib-v0.15.0
  • caosdb-pylib-v0.14.0
  • caosdb-pylib-v0.13.2
  • caosdb-server-v0.12.1
  • caosdb-pylib-v0.13.1
  • caosdb-pylib-v0.12.0
  • caosdb-server-v0.10.0
  • caosdb-pylib-v0.11.1
  • caosdb-pylib-v0.11.0
  • caosdb-server-v0.9.0
  • caosdb-pylib-v0.10.0
  • caosdb-server-v0.8.1
  • caosdb-pylib-v0.8.0
  • caosdb-server-v0.8.0
  • caosdb-pylib-v0.7.2
41 results

test_issues_server.py

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    test_issues_server.py 23.72 KiB
    # -*- coding: utf-8 -*-
    #
    # ** header v3.0
    # This file is a part of the CaosDB Project.
    #
    # Copyright (c) 2020 IndiScale GmbH <info@indiscale.com>
    # Copyright (c) 2020 Daniel Hornung <d.hornung@indiscale.com>
    # Copyright (c) 2020 Florian Spreckelsen <f.spreckelsen@indiscale.com>
    #
    # This program is free software: you can redistribute it and/or modify
    # it under the terms of the GNU Affero General Public License as
    # published by the Free Software Foundation, either version 3 of the
    # License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU Affero General Public License for more details.
    #
    # You should have received a copy of the GNU Affero General Public License
    # along with this program. If not, see <https://www.gnu.org/licenses/>.
    #
    # ** end header
    
    """Tests for issues on gitlab.com, project caosdb-server."""
    
    import math
    import os
    import tempfile
    import time
    
    import caosdb as db
    import pytest
    from caosdb.exceptions import TransactionError
    
    
    def setup_module():
        try:
            db.execute_query("FIND ENTITY WITH ID > 99").delete()
        except Exception as delete_exc:
            print(delete_exc)
    
    
    def setup_function(function):
        """No setup required."""
        setup_module()
    
    
    def teardown_function(function):
        """Deleting entities again."""
        setup_module()
    
    
    # ########################### Issue tests start here #####################
    
    
    def test_issue_39():
        """Query Language Bug - quotes around year
    
        Test for https://gitlab.com/caosdb/caosdb-server/-/issues/39
        """
        date_str = "2020-01-01"
        prop_name = "Test_Date"
        db.Property(name=prop_name, datatype=db.DATETIME).insert()
        db.RecordType(name="Test_Type").add_property(name=prop_name).insert()
        db.Record(name="Test_Record").add_parent(name="Test_Type").add_property(
            name=prop_name, value=date_str).insert()
        # Quotes around years should work in the query
        ent = db.execute_query("FIND entity WITH A Test_Date IN \"2020\"",
                               unique=True)
        assert ent.get_property(prop_name).value == date_str
        # This should raise a transaction error
        with pytest.raises(TransactionError):
            db.execute_query("FIND entity WITH A Test_Date IN \"abcd\"")
    
    
    @pytest.mark.xfail(reason="to be fixed in server repo")
    def test_issue_62():
        """datatype is not changed when recordtype name changes
    
        Tests for https://gitlab.com/caosdb/caosdb-server/-/issues/62
        """
        db.RecordType(name="Test_RTA").insert()
        db.Property(name="Test_Prop", datatype="Test_RTA").insert()
        db.Record(name="Test_Record").add_parent(
            name="Test_RTA").add_property(name="Test_Prop").insert()
        # rename Test_RTA to Test_RTB
        rtb = db.execute_query("FIND RecordType Test_RTA", unique=True)
        rtb.name = "Test_RTB"
        rtb.update()
        # renaming has to be reflected in Test_Record and Test_Prop
        rec = db.execute_query("FIND Record Test_Record", unique=True)
        assert rec.parents[0].name == rtb.name
        prop = db.execute_query("FIND Property Test_Prop", unique=True)
        assert prop.datatype == rtb.name  # fails; datatype not updated
        # Can't use Test_RTA as datatype anymore
        prop2 = db.Property(name="Test_Prop2", datatype="Test_RTA")
        with pytest.raises(TransactionError):
            prop2.insert()
    
    
    def test_issue_85_a():
        """SQLIntegrityConstraintViolationException for special inheritance patterns.
    
        Tests for https://gitlab.com/caosdb/caosdb-server/-/issues/85
        """
        A = db.RecordType(name="A")
        B = db.RecordType(name="B")
        C = db.RecordType(name="C")
    
        B.add_parent(A)
    
        # This order is important for the test to fail.
        C.add_parent(B)
        C.add_parent(C)
        C.add_parent(A)
    
        c = db.Container()
        # c.extend([C, B, A])  # worked before #86 was fixed
        # c.extend([C, A, B])  # worked before #86 was fixed
        c.extend([B, C, A])    # insert() failed before #86 was fixed
        c.insert()  # Raised java.sql.SQLIntegrityConstraintViolationException:
        #           # Duplicate entry '12345-12346-12345' for key 'PRIMARY'
    
    
    def test_issue_85_b():
        """SQLIntegrityConstraintViolationException for special inheritance patterns.
    
        Tests for https://gitlab.com/caosdb/caosdb-server/-/issues/85
        """
        A = db.RecordType(name="A")
        B = db.RecordType(name="B")
        C = db.RecordType(name="C")
        A.insert()
        B.insert()
        C.insert()
        B.add_parent(A)
        B.update()
        C.add_parent(B)
        C.update()
        C.add_parent(C)
        C.update()
        C.add_parent(A)
        C.update()  # Failed at this step
    
    
    @pytest.mark.local_server
    def test_issue_99():
        """Checksum updating failed with versioning enabled.
        """
    
        # Using files in extroot, because this allows us to update the file
        # content from the outside.
        local_dir = os.path.join(db.get_config().get("IntegrationTests",
                                                     "test_files.test_insert_files_in_dir.local"),
                                 "test_issue_99")
        docker_dir = os.path.join(db.get_config().get("IntegrationTests",
                                                      "test_files.test_insert_files_in_dir.server"),
                                  "test_issue_99")
        os.makedirs(local_dir, exist_ok=True)
        with tempfile.NamedTemporaryFile(dir=local_dir) as file_99:
            # Create File entity in CaosDB
            file_99.write("test 99\n".encode())
            os.fchmod(file_99.fileno(), 0o744)  # make the file world readable
            cont = db.Container()
            cont.insert(unique=False, raise_exception_on_error=False,
                        flags={"InsertFilesInDir": docker_dir})
            dbfile = cont[0]
    
            # Checksum should exist after a short time
            time.sleep(0.1)
            dbfile.retrieve()
            assert dbfile.checksum is not None
    
    
    def test_issue_110():
        """query ignores ID: FIND MusicalInstrument which is referenced by Analysis with ID=124 """
        cont = db.Container()
        A = db.RecordType(name="TypeA")
        B = db.RecordType(name="TypeB")
        prop = db.Property(name="prop_ba", datatype=db.REFERENCE)
    
        # Referenced Records
        a1 = db.Record().add_parent(A)
        a2 = db.Record().add_parent(A)
    
        # Referencing Records
        b1 = db.Record().add_parent(B).add_property(prop, value=a1)
        b2 = db.Record().add_parent(B).add_property(prop, value=a2)
    
        cont.extend([A, B, prop, a1, a2, b1, b2])
        cont.insert()
    
        id_b1 = b1.id
        query = "FIND TypeA WHICH IS REFERENCED BY TypeB WITH ID={}".format(id_b1)
        print(query)
        result = db.execute_query(query)
        print(result)
        assert len(result) == 1
        print(result[0])
        print(a1)
        assert result[0].id == a1.id
    
    
    def test_issue_120():
        """Editing entities that were created with a no longer existing user leads
        to a server error.
    
        The server should throw an error when CHECK_ENTITY_ACL_ROLES_MODE=MUST,
        otherwise a warning.
        """
        # insert an entity
        entity = db.RecordType("TestRT").insert(flags={"ACL": None})
    
        db.administration.set_server_property("CHECK_ENTITY_ACL_ROLES_MODE",
                                              "SHOULD")
        # update with non-existing user, realm and role
        entity.deny(
            realm="CaosDB",
            username="NON_EXISTING_USER",
            permission="USE:AS_REFERENCE")
        entity.update(flags={"ACL": None})
        assert entity.messages["Warning", 1104][0] == "User role does not exist."
    
        entity.deny(
            realm="NON_EXISTING_REALM",
            username="NON_EXISTING_USER",
            permission="USE:AS_REFERENCE")
        entity.update(flags={"ACL": None})
        assert entity.messages["Warning", 1104][0] == "User role does not exist."
    
        entity.deny(
            role="ALSO_NON_EXISTING_ROLE",
            permission="USE:AS_REFERENCE")
        entity.update(flags={"ACL": None})
        assert entity.messages["Warning", 1104][0] == "User role does not exist."
    
    
    def test_issue_134():
        """multiple white space characters after `FROM`"""
        db.execute_query("SELECT pname FROM  ename")
    
    
    def test_issue_131():
        """white space befor unit with strange character"""
        rt = db.RecordType(name="TestType").insert()
        prop = db.Property(name="TestProp", datatype=db.INTEGER, unit="").insert()
        rec = db.Record(name="TestRecord").add_property(
            name=prop.name, value=101, unit="")
        rec.add_parent(rt)
        rec.insert()
        result_ids = [ent.id for ent in db.execute_query(
            "FIND Entity WITH {} > 100 €".format(prop.name))]
    
        assert rec.id in result_ids
    
        result_ids = [ent.id for ent in db.execute_query(
            "FIND Entity WITH {} > 100.5 €".format(prop.name))]
    
        assert rec.id in result_ids
    
    
    def test_issue_154_no_versioning():
        """ FIND MusicalInstrument WITH Manufacturer = "Antonio Stradivari" and
        FIND MusicalInstrument WITH Manufacturer != "Antonio Stradivari" """
        rt_man = db.RecordType("Manufacturer")
        rt_inst = db.RecordType("MusicalInstrument").add_property(rt_man)
    
        rec_man = db.Record("Antonio Stradivari").add_parent("Manufacturer")
        rec_man2 = db.Record("The other guy").add_parent("Manufacturer")
        rec_inst = db.Record("Violin").add_parent(
            "MusicalInstrument").add_property("Manufacturer", rec_man)
        rec_inst2 = db.Record("Guitar").add_parent(
            "MusicalInstrument").add_property("Manufacturer", rec_man2)
        rec_inst3 = db.Record("Broken Record").add_parent("MusicalInstrument")
    
        c = db.Container().extend([rt_man, rt_inst, rec_man, rec_inst, rec_man2,
                                   rec_inst2, rec_inst3]).insert()
    
        assert "Violin" not in [e.name for e in db.execute_query(
            "FIND RECORD MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")]
        assert "Violin" not in [e.name for e in db.execute_query(
            "FIND RECORD MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")]
        assert len(db.execute_query("FIND MusicalInstrument")) == 4
        assert len(db.execute_query("FIND RECORD MusicalInstrument")) == 3
        assert len(db.execute_query(
            "FIND MusicalInstrument WITH Manufacturer")) == 3
        assert len(db.execute_query(
            "FIND RECORD MusicalInstrument WITH Manufacturer")) == 2
        assert rec_inst.id == db.execute_query(
            "FIND MusicalInstrument WITH Manufacturer = 'Antonio Stradivari'",
            unique=True).id
        assert len(db.execute_query(
            "FIND MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")) == 3
        assert len(db.execute_query(
            "FIND RECORD MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")) == 2
        assert len(db.execute_query(
            "FIND MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")) == 1
        assert len(db.execute_query(
            "FIND RECORD MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")) == 1
    
    
    def test_issue_154_with_versioning():
        """ FIND MusicalInstrument WITH Manufacturer = "Antonio Stradivari" and
        FIND MusicalInstrument WITH Manufacturer != "Antonio Stradivari" """
        rt_man = db.RecordType("Manufacturer")
        rt_inst = db.RecordType("MusicalInstrument").add_property(rt_man)
    
        rec_man = db.Record("Antonio Stradivari").add_parent("Manufacturer")
        rec_man2 = db.Record("The other guy").add_parent("Manufacturer")
        rec_inst = db.Record("Violin").add_parent(
            "MusicalInstrument").add_property("Manufacturer", rec_man)
        rec_inst2 = db.Record("Guitar").add_parent(
            "MusicalInstrument").add_property("Manufacturer", rec_man2)
        rec_inst3 = db.Record("Broken Record").add_parent("MusicalInstrument")
    
        db.Container().extend([rt_man, rt_inst, rec_man,
                               rec_inst, rec_man2, rec_inst2, rec_inst3]).insert()
    
        assert "Violin" not in [e.name for e in db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")]
        assert "Violin" not in [e.name for e in db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")]
        assert len(db.execute_query("FIND ANY VERSION OF MusicalInstrument")) == 4
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument")) == 3
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH Manufacturer")) == 3
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH Manufacturer")) == 2
        assert rec_inst.id == db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH Manufacturer = 'Antonio Stradivari'",
            unique=True).id
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")) == 3
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")) == 2
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")) == 1
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")) == 1
    
        # now, some updates
        rt_man.description = "Updated Description"
        rt_inst.description = "Updated Description"
    
        rec_man.description = "Updated Description"
        rec_man2.description = "Updated Description"
        rec_inst.description = "Updated Description"
        rec_inst2.description = "Updated Description"
        rec_inst3.description = "Updated Description"
        db.Container().extend([rt_man, rt_inst, rec_man,
                               rec_inst, rec_man2, rec_inst2, rec_inst3]).update()
    
        assert "Violin" not in [e.name for e in db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")]
        assert "Violin" not in [e.name for e in db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")]
        assert len(db.execute_query("FIND ANY VERSION OF MusicalInstrument")) == 8
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument")) == 6
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH Manufacturer")) == 6
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH Manufacturer")) == 4
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH Manufacturer = 'Antonio Stradivari'")) == 2
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")) == 6
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH NOT Manufacturer = 'Antonio Stradivari'")) == 4
        assert len(db.execute_query(
            "FIND ANY VERSION OF MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")) == 2
        assert len(db.execute_query(
            "FIND ANY VERSION OF RECORD MusicalInstrument WITH Manufacturer != 'Antonio Stradivari'")) == 2
    
    
    def test_issue_127():
        """https://gitlab.com/caosdb/caosdb-server/-/issues/127"""
        p = db.Property(
            name="TestDoubleProperty",
            datatype=db.LIST(
                db.DOUBLE)).insert()
        rt = db.RecordType(name="TestRecordType").add_property(name="TestDoubleProperty",
                                                               value=["nan"]).insert()
    
        test1 = db.execute_query("FIND TestRecordType", unique=True)
        assert math.isnan(test1.get_property("TestDoubleProperty").value[0])
    
        test2 = db.execute_query(
            "FIND TestRecordType WITH TestDoubleProperty = NaN", unique=True)
        assert math.isnan(test1.get_property("TestDoubleProperty").value[0])
    
    
    def test_issue_170():
        """update scalar data type to list data type"""
        p = db.Property(name="TestProp1", datatype=db.LIST(db.INTEGER))
        p.value = [1, 2]
        p.insert()
    
        p2 = db.execute_query("FIND TestProp1", unique=True)
        assert p2.datatype == db.LIST(db.INTEGER)
        assert p2.value == [1, 2]
    
        p.description = "TestDescription"
        p.update()  # this failed
    
        p2 = db.execute_query("FIND TestProp1", unique=True)
        assert p2.datatype == db.LIST(db.INTEGER)
        assert p2.value == [1, 2]
        assert p2.description == "TestDescription"
    
        p = db.Property(name="TestProp2", datatype=db.DOUBLE)
        p.insert()
    
        p.datatype = db.LIST(db.INTEGER)
        p.update()  # this worked because no value yet
        p2 = db.execute_query("FIND TestProp2", unique=True)
        assert p2.datatype == db.LIST(db.INTEGER)
        p.value = [1, 2]
    
        p.update()  # this failed
        p2 = db.execute_query("FIND TestProp2", unique=True)
        assert p2.datatype == db.LIST(db.INTEGER)
        assert p2.value == [1, 2]
    
        p = db.Property(name="TestProp3", datatype=db.DOUBLE)
        p.insert()
    
        p.datatype = db.LIST(db.INTEGER)
        p.value = [1, 2]
        p.update()  # this failed
    
        p2 = db.execute_query("FIND TestProp3", unique=True)
        assert p2.datatype == db.LIST(db.INTEGER)
        assert p2.value == [1, 2]
    
    
    def test_issue_181():
        """https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/181"""
        rt = db.RecordType("TestRT").insert()
        assert len(db.execute_query("FIND RECORDTYPE TestRT")) == 1
        assert len(db.execute_query(
            "FIND RECORDTYPE TestRT WHICH HAS BEEN UPDATED TODAY")) == 0
        rt.description = "New description"
        rt.update()
        assert len(db.execute_query(
            "FIND RECORDTYPE TestRT WHICH HAS BEEN UPDATED TODAY")) == 1
    
    
    def test_issue_183():
        """No reasonable error when using bad datetime format.
        https://gitlab.indiscale.com/caosdb/src/caosdb-server/-/issues/183
        """
    
        # Date YYYY-MM-ddThh:mm:ss
        assert db.Property(name="TestDateTime", datatype=db.DATETIME,
                           value="2015-05-05T20:15:00").insert().id is not None
        with pytest.raises(db.TransactionError) as cm:
            # Date YYYY-MM-ddThh:mm
            db.Property(name="TestDateTime2", datatype=db.DATETIME,
                        value="2015-05-05T20:15").insert()
        assert cm.value.errors[0].msg == ("Cannot parse value to datetime format "
                                          "(yyyy-mm-dd'T'hh:mm:ss[.fffffffff][TimeZone]).")
    
    
    @pytest.mark.xfail(reason="fix https://gitlab.com/caosdb/caosdb-server/-/issues/130")
    def test_issue_130():
        """Test select queries where names contain spaces
    
        https://gitlab.com/caosdb/caosdb-server/-/issues/130
    
        However, this bug was actually about quotation marks
        """
        db.RecordType(name="TestRT_A").insert()
        r1 = db.Record("ReferencedRecord").add_parent("TestRT_A").insert()
        p1 = db.Property(name="TestWrapper", datatype="TestRT_A").insert()
        p2 = db.Property(
            name="TestWrapper With Spaces",
            datatype="TestRT_A").insert()
        db.RecordType(name="TestRT_B"
                      ).add_property(name="TestWrapper"
                                     ).add_property("TestWrapper With Spaces"
                                                    ).insert()
        db.Record().add_parent("TestRT_B"
                               ).add_property("TestWrapper", value=r1
                                              ).add_property("TestWrapper With Spaces",
                                                             value=r1
                                                             ).insert()
    
        query = "SELECT TestWrapper FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper"))
        assert row == [(r1.id,)]
    
        query = "SELECT TestWrapper FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper", "id"))
        assert row == [(p1.id,)]
    
        query = "SELECT 'TestWrapper' FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper", "id"))
        assert row == [(r1.id,)]  # FAILS
    
        query = "SELECT TestWrapper FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
        assert row == [("TestWrapper",)]
    
        query = "SELECT TestWrapper.name FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
        assert row == [("ReferencedRecord",)]
    
        query = "SELECT 'TestWrapper.name' FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
        assert row == [("ReferencedRecord",)]  # FAILS
    
        query = "SELECT 'TestWrapper'.name FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(("TestWrapper", "name"))
        assert row == [("ReferencedRecord",)]  # FAILS
    
        query = "SELECT TestWrapper With Spaces FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces"))
        assert row == [(r1.id,)]
    
        query = "SELECT TestWrapper With Spaces FROM RECORD TestRT_B"
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces", "id"))
        assert row == [(p2.id,)]
    
        query = 'SELECT TestWrapper With Spaces FROM RECORD TestRT_B'
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces", "name"))
        assert row == [("TestWrapper With Spaces",)]
    
        query = 'SELECT "TestWrapper With Spaces" FROM RECORD TestRT_B'
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces", "name"))
        assert row == [("ReferencedRecord",)]  # FAILS
    
        query = 'SELECT TestWrapper With Spaces.name FROM RECORD TestRT_B'
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces", "name"))
        # Works!!! This is about the quotation marks
        assert row == [("ReferencedRecord",)]
    
        query = 'SELECT "TestWrapper With Spaces.name" FROM RECORD TestRT_B'
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces", "name"))
        assert row == [("ReferencedRecord",)]  # FAILS
    
        query = 'SELECT "TestWrapper With Spaces".name FROM RECORD TestRT_B'
        row = db.execute_query(query).get_property_values(
            ("TestWrapper With Spaces", "name"))
        assert row == [("ReferencedRecord",)]  # FAILS
    
    
    def test_issue_132():
        """Query: Parenthesis around subproperties.
    
        https://gitlab.com/caosdb/caosdb-server/-/issues/132
        """
        db.RecordType("TestRT").insert()
        db.RecordType("TestRT_Foo").insert()
        db.Property("TestP_Bar", datatype=db.TEXT).insert()
        db.Property("TestP_Baz", datatype=db.TEXT).insert()
    
        rt1 = db.Record().add_parent("TestRT_Foo").add_property(
            "TestP_Bar", "val1").add_property(
            "TestP_Baz", "the other baz").insert()
        rt2 = db.Record().add_parent("TestRT").add_property(
            "TestP_Baz", "val2").add_property(
            "TestRT_Foo", rt1).insert()
    
        query = "FIND RECORD TestRT_Foo"
        assert db.execute_query(query, unique=True).id == rt1.id
    
        query = "FIND RECORD TestRT"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH TestRT_Foo"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH TestRT_Foo.TestP_Bar"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH TestRT_Foo.TestP_Bar = val1"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH (TestRT_Foo.TestP_Bar = val1)"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH ( TestRT_Foo.TestP_Bar = val1 )"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH (TestRT_Foo.TestP_Bar = val1) AND TestP_Baz = val2"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH (TestRT_Foo WITH (TestP_Bar = val1 AND TestP_Baz = 'the other baz')) AND TestP_Baz = val2"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        query = "FIND RECORD TestRT WITH TestRT_Foo WITH (TestP_Bar = val1 AND TestP_Baz = 'the other baz') AND TestP_Baz = val2"
        assert db.execute_query(query, unique=True).id == rt2.id
    
        # this one has the wront scope of the conjunction.
        query = "FIND RECORD TestRT WITH TestRT_Foo.TestP_Bar = val1 AND TestP_Baz = 'the other one'"
        assert len(db.execute_query(query)) == 0