cubicweb #715951 changeset 921737d2e3a8 breaks Pylos (RQLUniqueConstraint) [rejected]

the change labelled 'fix optimisation with super session that may lead to integrity loss' breaks some constraint checking in Pylos.

To sum up what's happening: various entities are related to a Case entity though a Case case_of Entity relation. This is defined in the schema using:

def setup_case_of_relation(schema):
    _rtypes, etypes = schema.case_rtypes_etypes()
    schema.add_relation_type(RelationType('case_of'))
    for etype in etypes:
        schema.add_relation_def(RelationDefinition('Case', 'case_of', etype,
                                                  cardinality='?*'))

(where case_rtypes_etypes uses some introspection on the schema to tell which entities are concerned)

This link is established via a hook:

class SetCaseOfRelation(Hook):
    __regid__ = 'pegase_set_case_of_relation'
    events = ('after_add_entity',)
    __select__ = Hook.__select__ & implements('Any')

    def __call__(self):
        AddCaseOfRelationOp(self._cw, entity=self.entity)

class AddCaseOfRelationOp(Operation):
    """
    when all relations are set, we set case_of
    """
    def insert_index(self):
        return 0

    def precommit_event(self):
        session = self.session
        entity = self.entity #pylint:disable-msg=E1101
        case = entity.related_case
        if case is not None and hasattr(entity, 'reverse_case_of'):
            session.unsafe_execute('SET C case_of E WHERE C eid %(c)s, E eid %(e)s',
                                   {'c': case.eid, 'e': entity.eid})

Before and after the changeset, the hook and operation are called, but the effect is different :

  • before the changeset, various entities are linked to the Case after the creation of a given case with associated entities
  • after the changeset, only the last entity for which the hook was called is linked
priorityimportant
typebug
done in3.6.1
load0.000
load left0.000
closed by<not specified>