# HG changeset patch # User Aurelien Campeas # Date 1443013233 -7200 # Node ID 80236876ee4dd09d8a04a6909335b978f2ec0bfa # Parent 743ed2b13a6f83122ba2713e0b881d5c606cd01a [hooks/syncschema] only call "ALTER TABLE" once when changing a size constraint Until now we would: - remove the old size constraint from the in-memory schema - call update_rdef_column which removes the size restriction from the column's type - add the new constraint object - call update_rdef_column which adds the size restriction back This breaks on SQL Server when the column is involved in an index (e.g. as part of a multi-column unique constraint), because in the intermediate stage the column's type is "nvarchar(max)", which is not indexable. Of course we must still detect the case where a size constraint is really dropped and update the db schema accordingly. Closes #5557633. diff -r 743ed2b13a6f -r 80236876ee4d hooks/syncschema.py --- a/hooks/syncschema.py Wed Sep 02 15:24:46 2015 +0200 +++ b/hooks/syncschema.py Wed Sep 23 15:00:33 2015 +0200 @@ -661,6 +661,16 @@ syssource = cnx.repo.system_source cstrtype = self.oldcstr.type() if cstrtype == 'SizeConstraint': + # if the size constraint is being replaced with a new max size, we'll + # call update_rdef_column in CWConstraintAddOp, skip it here + for cstr in cnx.transaction_data.get('newsizecstr', ()): + rdefentity = cstr.reverse_constrained_by[0] + cstrrdef = cnx.vreg.schema.schema_by_eid(rdefentity.eid) + if cstrrdef == rdef: + return + + # we found that the size constraint for this rdef is really gone, + # not just replaced by another syssource.update_rdef_column(cnx, rdef) self.size_cstr_changed = True elif cstrtype == 'UniqueConstraint': @@ -1114,6 +1124,11 @@ events = ('after_add_entity', 'after_update_entity') def __call__(self): + if self.entity.cstrtype[0].name == 'SizeConstraint': + txdata = self._cw.transaction_data + if 'newsizecstr' not in txdata: + txdata['newsizecstr'] = set() + txdata['newsizecstr'].add(self.entity) CWConstraintAddOp(self._cw, entity=self.entity)