[IMP] orm._auto_init: avoid copying VARCHAR column when increasing size, alter in-place instead + better temporary names

Historically, we used a copy+rename technique during
table upgrades to alter varchar columns sizes.
This was only necessary to permit downsizing
columns, which we do not want to do anymore (it is
too dangerous, so has to be done explicitly when
required).

Switching to a pure ALTER COLUMN TYPE is simpler
and also much faster for large tables.

Also fixed the inappropriate name used for
temporary columns during column type casting
(which *does* require the copy+rename technique).

bzr revid: odo@openerp.com-20140217164239-0iou3dsiea3foabb
This commit is contained in:
Olivier Dony 2014-02-17 17:42:39 +01:00
parent 122c66725c
commit a5b51c2be7
1 changed files with 4 additions and 7 deletions

View File

@ -2716,10 +2716,7 @@ class BaseModel(object):
('float8', 'float', get_pg_type(f)[1], '::'+get_pg_type(f)[1]),
]
if f_pg_type == 'varchar' and f._type == 'char' and ((f.size is None and f_pg_size) or f_pg_size < f.size):
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, pg_varchar(f.size)))
cr.execute('UPDATE "%s" SET "%s"=temp_change_size::%s' % (self._table, k, pg_varchar(f.size)))
cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" TYPE %s' % (self._table, k, pg_varchar(f.size)))
cr.commit()
_schema.debug("Table '%s': column '%s' (type varchar) changed size from %s to %s",
self._table, k, f_pg_size or 'unlimited', f.size or 'unlimited')
@ -2727,10 +2724,10 @@ class BaseModel(object):
if (f_pg_type==c[0]) and (f._type==c[1]):
if f_pg_type != f_obj_type:
ok = True
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO temp_change_size' % (self._table, k))
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO __temp_type_cast' % (self._table, k))
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, c[2]))
cr.execute(('UPDATE "%s" SET "%s"=temp_change_size'+c[3]) % (self._table, k))
cr.execute('ALTER TABLE "%s" DROP COLUMN temp_change_size CASCADE' % (self._table,))
cr.execute(('UPDATE "%s" SET "%s"= __temp_type_cast'+c[3]) % (self._table, k))
cr.execute('ALTER TABLE "%s" DROP COLUMN __temp_type_cast CASCADE' % (self._table,))
cr.commit()
_schema.debug("Table '%s': column '%s' changed type from %s to %s",
self._table, k, c[0], c[1])