You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ma...@apache.org on 2018/04/04 07:36:30 UTC

[incubator-superset] branch master updated: [BUGFIX]: JavaScripts max int is 2^53 - 1, longs are bigger (#4005)

This is an automated email from the ASF dual-hosted git repository.

maximebeauchemin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 9a79d33  [BUGFIX]: JavaScripts max int is 2^53 - 1, longs are bigger (#4005)
9a79d33 is described below

commit 9a79d33e0d19e8b49fa0392f877fd7bf4c457a22
Author: fabianmenges <fa...@users.noreply.github.com>
AuthorDate: Wed Apr 4 03:36:23 2018 -0400

    [BUGFIX]: JavaScripts max int is 2^53 - 1, longs are bigger (#4005)
    
    * [BUGFIX]: Java scripts max int is 2^53 - 1 longs are bigger and frequently used as IDs this is a hacky fix.
    
    * Keep tuple as tuple
---
 superset/dataframe.py | 13 +++++++++++--
 superset/utils.py     |  2 ++
 superset/viz.py       | 31 +++++++++++++++++++++++++------
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/superset/dataframe.py b/superset/dataframe.py
index 62d6cf4..38c4fb5 100644
--- a/superset/dataframe.py
+++ b/superset/dataframe.py
@@ -19,6 +19,7 @@ from pandas.core.common import _maybe_box_datetimelike
 from pandas.core.dtypes.dtypes import ExtensionDtype
 from past.builtins import basestring
 
+from superset.utils import JS_MAX_INTEGER
 
 INFER_COL_TYPES_THRESHOLD = 95
 INFER_COL_TYPES_SAMPLE_SIZE = 100
@@ -51,9 +52,17 @@ class SupersetDataFrame(object):
     @property
     def data(self):
         # work around for https://github.com/pandas-dev/pandas/issues/18372
-        return [dict((k, _maybe_box_datetimelike(v))
-                     for k, v in zip(self.__df.columns, np.atleast_1d(row)))
+        data = [dict((k, _maybe_box_datetimelike(v))
+                for k, v in zip(self.__df.columns, np.atleast_1d(row)))
                 for row in self.__df.values]
+        for d in data:
+            for k, v in list(d.items()):
+                # if an int is too big for Java Script to handle
+                # convert it to a string
+                if isinstance(v, int):
+                    if abs(v) > JS_MAX_INTEGER:
+                        d[k] = str(v)
+        return data
 
     @classmethod
     def db_type(cls, dtype):
diff --git a/superset/utils.py b/superset/utils.py
index 828111f..8e99f69 100644
--- a/superset/utils.py
+++ b/superset/utils.py
@@ -48,6 +48,8 @@ PY3K = sys.version_info >= (3, 0)
 EPOCH = datetime(1970, 1, 1)
 DTTM_ALIAS = '__timestamp'
 
+JS_MAX_INTEGER = 9007199254740991   # Largest int Java Script can handle 2^53-1
+
 
 def flasher(msg, severity=None):
     """Flask's flash if available, logging call if not"""
diff --git a/superset/viz.py b/superset/viz.py
index cb20e11..af8a149 100644
--- a/superset/viz.py
+++ b/superset/viz.py
@@ -35,7 +35,7 @@ from six import string_types, text_type
 from six.moves import cPickle as pkl, reduce
 
 from superset import app, cache, get_manifest_file, utils
-from superset.utils import DTTM_ALIAS, merge_extra_filters
+from superset.utils import DTTM_ALIAS, JS_MAX_INTEGER, merge_extra_filters
 
 
 config = app.config
@@ -88,6 +88,17 @@ class BaseViz(object):
         self._any_cached_dttm = None
         self._extra_chart_data = None
 
+    @staticmethod
+    def handle_js_int_overflow(data):
+        for d in data.get('records', dict()):
+            for k, v in list(d.items()):
+                if isinstance(v, int):
+                    # if an int is too big for Java Script to handle
+                    # convert it to a string
+                    if abs(v) > JS_MAX_INTEGER:
+                        d[k] = str(v)
+        return data
+
     def run_extra_queries(self):
         """Lyfecycle method to use when more than one query is needed
 
@@ -515,10 +526,13 @@ class TableViz(BaseViz):
             ):
                 del df[m]
 
-        return dict(
-            records=df.to_dict(orient='records'),
-            columns=list(df.columns),
-        )
+        data = self.handle_js_int_overflow(
+            dict(
+                records=df.to_dict(orient='records'),
+                columns=list(df.columns),
+            ))
+
+        return data
 
     def json_dumps(self, obj, sort_keys=False):
         if self.form_data.get('all_columns'):
@@ -1033,7 +1047,12 @@ class NVD3TimeSeriesViz(NVD3Viz):
             ys = series[name]
             if df[name].dtype.kind not in 'biufc':
                 continue
-            series_title = name
+            if isinstance(name, list):
+                series_title = [str(title) for title in name]
+            elif isinstance(name, tuple):
+                series_title = tuple(str(title) for title in name)
+            else:
+                series_title = str(name)
             if (
                     isinstance(series_title, (list, tuple)) and
                     len(series_title) > 1 and

-- 
To stop receiving notification emails like this one, please contact
maximebeauchemin@apache.org.