From 11f538fae66f8d1c1c715d1d9726e2bc0e80cad0 Mon Sep 17 00:00:00 2001 From: Thomas Rehn Date: Tue, 8 Sep 2015 11:40:42 +0200 Subject: [PATCH] [FIX] expression: table alias reaching 64 characters limits Postgresql has a limit of 64 characters for tables, columns names as well as for aliases names. When generating an alias name, e.g. for group by and order by clauses, if the alias is longer than 64 characters, use hashing to force the alias length to be within this 64 chars limit. Fixes #8094 Closes #8142 --- openerp/osv/expression.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index dedd043ca90..dbad00d6e80 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -135,6 +135,7 @@ import collections import logging import traceback +from zlib import crc32 import openerp.modules from . import fields @@ -343,7 +344,16 @@ def generate_table_alias(src_table_alias, joined_tables=[]): return '%s' % alias, '%s' % _quote(alias) for link in joined_tables: alias += '__' + link[1] - assert len(alias) < 64, 'Table alias name %s is longer than the 64 characters size accepted by default in postgresql.' % alias + # Use an alternate alias scheme if length exceeds the PostgreSQL limit + # of 63 characters. + if len(alias) >= 64: + # We have to fit a crc32 hash and one underscore + # into a 63 character alias. The remaining space we can use to add + # a human readable prefix. + alias_hash = hex(crc32(alias))[2:] + ALIAS_PREFIX_LENGTH = 63 - len(alias_hash) - 1 + alias = "%s_%s" % ( + alias[:ALIAS_PREFIX_LENGTH], alias_hash) return '%s' % alias, '%s as %s' % (_quote(joined_tables[-1][0]), _quote(alias))