[1.11.x] Fixed #27843 -- Fixed truncate_name() when the name contains a username.

Backport of b935190572 from master
This commit is contained in:
Mariusz Felisiak 2017-02-15 12:22:34 +01:00 committed by Tim Graham
parent a66f448f11
commit 87775b64cd
2 changed files with 15 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import datetime
import decimal
import hashlib
import logging
import re
from time import time
from django.conf import settings
@ -180,13 +181,19 @@ def rev_typecast_decimal(d):
def truncate_name(name, length=None, hash_len=4):
"""Shortens a string to a repeatable mangled version with the given length.
"""
if length is None or len(name) <= length:
Shorten a string to a repeatable mangled version with the given length.
If a quote stripped name contains a username, e.g. USERNAME"."TABLE,
truncate the table portion only.
"""
match = re.match('([^"]+)"\."([^"]+)', name)
table_name = match.group(2) if match else name
if length is None or len(table_name) <= length:
return name
hsh = hashlib.md5(force_bytes(name)).hexdigest()[:hash_len]
return '%s%s' % (name[:length - hash_len], hsh)
hsh = hashlib.md5(force_bytes(table_name)).hexdigest()[:hash_len]
return '%s%s%s' % (match.group(1) + '"."' if match else '', table_name[:length - hash_len], hsh)
def format_number(value, max_digits, decimal_places):

View File

@ -21,3 +21,7 @@ class TestLoadBackend(SimpleTestCase):
self.assertEqual(truncate_name('some_long_table', 10), 'some_la38a')
self.assertEqual(truncate_name('some_long_table', 10, 3), 'some_loa38')
self.assertEqual(truncate_name('some_long_table'), 'some_long_table')
# "user"."table" syntax
self.assertEqual(truncate_name('username"."some_table', 10), 'username"."some_table')
self.assertEqual(truncate_name('username"."some_long_table', 10), 'username"."some_la38a')
self.assertEqual(truncate_name('username"."some_long_table', 10, 3), 'username"."some_loa38')