[FIX] ir_sequence: add support for PG 10

PostgreSQL 10 move sequences' metadata fields into a new `pg_sequence`
system catalog. As a result, selecting from a sequence relation now
only return three fields, and does not include the `increment_by`
metadata field anymore.

This patch obtains the `increment_by` value from the new system catalog
for PostgreSQL server versions >= 10.

Fixes #20269
This commit is contained in:
Olivier Dony
2017-11-11 00:51:36 +01:00
parent ae2cbc7a01
commit 7a4c6eb35d
+22 -17
View File
@@ -54,6 +54,24 @@ def _update_nogap(self, number_increment):
self.invalidate_cache(['number_next'], [self.id])
return number_next
def _predict_nextval(self, seq_id):
"""Predict next value for PostgreSQL sequence without consuming it"""
# Cannot use currval() as it requires prior call to nextval()
query = """SELECT last_value,
(SELECT increment_by
FROM pg_sequences
WHERE sequencename = 'ir_sequence_%(seq_id)s'),
is_called
FROM ir_sequence_%(seq_id)s"""
if self.env.cr._cnx.server_version < 100000:
query = "SELECT last_value, increment_by, is_called FROM ir_sequence_%(seq_id)s"
self.env.cr.execute(query % {'seq_id': seq_id})
(last_value, increment_by, is_called) = self.env.cr.fetchone()
if is_called:
return last_value + increment_by
# sequence has just been RESTARTed to return last_value next time
return last_value
class IrSequence(models.Model):
""" Sequence model.
@@ -73,15 +91,8 @@ class IrSequence(models.Model):
if seq.implementation != 'standard':
seq.number_next_actual = seq.number_next
else:
# get number from postgres sequence. Cannot use currval, because that might give an error when
# not having used nextval before.
query = "SELECT last_value, increment_by, is_called FROM ir_sequence_%03d" % seq.id
self._cr.execute(query)
(last_value, increment_by, is_called) = self._cr.fetchone()
if is_called:
seq.number_next_actual = last_value + increment_by
else:
seq.number_next_actual = last_value
seq_id = "%03d" % seq.id
seq.number_next_actual = _predict_nextval(self, seq_id)
def _set_number_next_actual(self):
for seq in self:
@@ -293,14 +304,8 @@ class IrSequenceDateRange(models.Model):
if seq.sequence_id.implementation != 'standard':
seq.number_next_actual = seq.number_next
else:
# get number from postgres sequence. Cannot use currval, because that might give an error when
# not having used nextval before.
self._cr.execute("SELECT last_value, increment_by, is_called FROM ir_sequence_%03d_%03d" % (seq.sequence_id.id, seq.id))
(last_value, increment_by, is_called) = self._cr.fetchone()
if is_called:
seq.number_next_actual = last_value + increment_by
else:
seq.number_next_actual = last_value
seq_id = "%03d_%03d" % (seq.sequence_id.id, seq.id)
seq.number_next_actual = _predict_nextval(self, seq_id)
def _set_number_next_actual(self):
for seq in self: