From 84f7ea1cec1626893b56e2ee9f8bc06bfa602926 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 6 Feb 2019 16:09:16 +0530 Subject: [PATCH] fix: max value for int types --- frappe/database/mariadb/database.py | 2 +- frappe/database/postgres/database.py | 2 +- frappe/model/base_document.py | 32 ++++++++++++++++++++-------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/frappe/database/mariadb/database.py b/frappe/database/mariadb/database.py index 30ef20467f..8a95bba228 100644 --- a/frappe/database/mariadb/database.py +++ b/frappe/database/mariadb/database.py @@ -27,7 +27,7 @@ class MariaDBDatabase(Database): self.type_map = { 'Currency': ('decimal', '18,6'), 'Int': ('int', '11'), - 'Long Int': ('bigint', '20'), # convert int to bigint if length is more than 11 + 'Long Int': ('bigint', '20'), 'Float': ('decimal', '18,6'), 'Percent': ('decimal', '18,6'), 'Check': ('int', '1'), diff --git a/frappe/database/postgres/database.py b/frappe/database/postgres/database.py index d355daf296..fb0908ca65 100644 --- a/frappe/database/postgres/database.py +++ b/frappe/database/postgres/database.py @@ -32,7 +32,7 @@ class PostgresDatabase(Database): self.type_map = { 'Currency': ('decimal', '18,6'), 'Int': ('bigint', None), - 'Long Int': ('bigint', None), # convert int to bigint if length is more than 11 + 'Long Int': ('bigint', None), 'Float': ('decimal', '18,6'), 'Percent': ('decimal', '18,6'), 'Check': ('smallint', None), diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index 3b9b3765aa..8527828404 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -16,6 +16,12 @@ from frappe.utils.password import get_decrypted_password, set_encrypted_password from frappe.utils import (cint, flt, now, cstr, strip_html, getdate, get_datetime, to_timedelta, sanitize_html, sanitize_email, cast_fieldtype) +max_positive_value = { + 'smallint': 2 ** 15, + 'int': 2 ** 31, + 'bigint': 2 ** 63 +} + _classes = {} def get_controller(doctype): @@ -549,7 +555,6 @@ class BaseDocument(object): # single doctype value type is mediumtext return - column_types_to_check_length = ('varchar', 'int', 'bigint') type_map = frappe.db.type_map for fieldname, value in iteritems(self.get_valid_dict()): @@ -560,20 +565,29 @@ class BaseDocument(object): continue column_type = type_map[df.fieldtype][0] or None - default_column_max_length = type_map[df.fieldtype][1] or None - if df and df.fieldtype in type_map and column_type in column_types_to_check_length: + if column_type == 'varchar': + default_column_max_length = type_map[df.fieldtype][1] or None max_length = cint(df.get("length")) or cint(default_column_max_length) if len(cstr(value)) > max_length: - if self.parentfield and self.idx: - reference = _("{0}, Row {1}").format(_(self.doctype), self.idx) + self.throw_length_exceeded_error(df, max_length, value) - else: - reference = "{0} {1}".format(_(self.doctype), self.name) + elif column_type in ('int', 'bigint', 'smallint'): + max_length = max_positive_value[column_type] - frappe.throw(_("{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}")\ - .format(reference, _(df.label), max_length, value), frappe.CharacterLengthExceededError, title=_('Value too big')) + if abs(value) > max_length: + self.throw_length_exceeded_error(df, max_length, value) + + def throw_length_exceeded_error(self, df, max_length, value): + if self.parentfield and self.idx: + reference = _("{0}, Row {1}").format(_(self.doctype), self.idx) + + else: + reference = "{0} {1}".format(_(self.doctype), self.name) + + frappe.throw(_("{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}")\ + .format(reference, _(df.label), max_length, value), frappe.CharacterLengthExceededError, title=_('Value too big')) def _validate_update_after_submit(self): # get the full doc with children