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

Backport of b9351905721771fb49ea0020c751ae4280754c43 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 decimal
import hashlib import hashlib
import logging import logging
import re
from time import time from time import time
from django.conf import settings from django.conf import settings
@ -180,13 +181,19 @@ def rev_typecast_decimal(d):
def truncate_name(name, length=None, hash_len=4): 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 return name
hsh = hashlib.md5(force_bytes(name)).hexdigest()[:hash_len] hsh = hashlib.md5(force_bytes(table_name)).hexdigest()[:hash_len]
return '%s%s' % (name[:length - hash_len], hsh) return '%s%s%s' % (match.group(1) + '"."' if match else '', table_name[:length - hash_len], hsh)
def format_number(value, max_digits, decimal_places): 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), 'some_la38a')
self.assertEqual(truncate_name('some_long_table', 10, 3), 'some_loa38') self.assertEqual(truncate_name('some_long_table', 10, 3), 'some_loa38')
self.assertEqual(truncate_name('some_long_table'), 'some_long_table') 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')