From 3c08e618bd31587f98e6653286b0914661b65cc4 Mon Sep 17 00:00:00 2001 From: Yogesh Mahajan Date: Thu, 9 Jul 2020 18:11:46 +0530 Subject: [PATCH] Fixed an issue where CSV download quotes numeric columns. Fixes #5463 --- docs/en_US/release_notes_4_24.rst | 1 + .../utils/driver/psycopg2/connection.py | 7 +++++- web/pgadmin/utils/driver/psycopg2/typecast.py | 23 +++++++++++++------ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/docs/en_US/release_notes_4_24.rst b/docs/en_US/release_notes_4_24.rst index 4d98f3e3e..30b7615af 100644 --- a/docs/en_US/release_notes_4_24.rst +++ b/docs/en_US/release_notes_4_24.rst @@ -26,6 +26,7 @@ Bug fixes | `Issue #3851 `_ - Add proper indentation to the code while generating functions, procedures, and trigger functions. | `Issue #4235 `_ - Fixed tab indent issue on a selection of lines is deleting the content when 'use spaces == true' in the preferences. | `Issue #5287 `_ - Fixed dark theme-related CSS and modify the color codes. +| `Issue #5463 `_ - Fixed an issue where CSV download quotes numeric columns. | `Issue #5470 `_ - Fixed backgrid row hover issue where on hover background color is set for edit and delete cell only. | `Issue #5530 `_ - Ensure that the referenced table should be displayed on foreign key constraints. | `Issue #5621 `_ - Remove extra brackets from reverse engineering SQL of RLS Policy. diff --git a/web/pgadmin/utils/driver/psycopg2/connection.py b/web/pgadmin/utils/driver/psycopg2/connection.py index 0683e4eff..52617d6b4 100644 --- a/web/pgadmin/utils/driver/psycopg2/connection.py +++ b/web/pgadmin/utils/driver/psycopg2/connection.py @@ -33,6 +33,7 @@ from ..abstract import BaseConnection from .cursor import DictCursor from .typecast import register_global_typecasters, \ register_string_typecasters, register_binary_typecasters, \ + unregister_numeric_typecasters, \ register_array_to_string_typecasters, ALL_JSON_TYPES from .encoding import getEncoding, configureDriverEncodings from pgadmin.utils import csv @@ -689,6 +690,8 @@ WHERE ) ) try: + # Unregistering type casting for large size data types. + unregister_numeric_typecasters(self.conn) self.__internal_blocking_execute(cur, query, params) except psycopg2.Error as pe: cur.close() @@ -834,7 +837,9 @@ WHERE results = handle_null_values(results, replace_nulls_with) csv_writer.writerows(results) yield res_io.getvalue() - + # Registering back type caster for large size data types to string + # which was unregistered at starting + register_string_typecasters(self.conn) return True, gen def execute_scalar(self, query, params=None, diff --git a/web/pgadmin/utils/driver/psycopg2/typecast.py b/web/pgadmin/utils/driver/psycopg2/typecast.py index 5b8810e24..b84b62bf0 100644 --- a/web/pgadmin/utils/driver/psycopg2/typecast.py +++ b/web/pgadmin/utils/driver/psycopg2/typecast.py @@ -13,8 +13,8 @@ data types. """ from psycopg2 import STRING as _STRING +from psycopg2.extensions import DECIMAL as _DECIMAL, encodings import psycopg2 -from psycopg2.extensions import encodings from psycopg2.extras import Json as psycopg2_json from .encoding import configureDriverEncodings, getEncoding @@ -33,11 +33,13 @@ TO_STRING_DATATYPES = ( # To cast bytea, interval type 17, 1186, - # date, timestamp, timestamptz, bigint, double precision - 1700, 1082, 1114, 1184, 20, 701, + # date, timestamp, timestamp with zone, time without time zone + 1082, 1114, 1184, 1083 +) - # real, time without time zone - 700, 1083 +TO_STRING_NUMERIC_DATATYPES = ( + # Real, double precision, numeric, bigint + 700, 701, 1700, 20 ) # OIDs of array data types which need to typecast to array of string. @@ -142,8 +144,8 @@ def register_global_typecasters(): # define type caster to convert various pg types into string type pg_types_to_string_type = psycopg2.extensions.new_type( - TO_STRING_DATATYPES + PSYCOPG_SUPPORTED_RANGE_TYPES, - 'TYPECAST_TO_STRING', _STRING + TO_STRING_DATATYPES + TO_STRING_NUMERIC_DATATYPES + + PSYCOPG_SUPPORTED_RANGE_TYPES, 'TYPECAST_TO_STRING', _STRING ) # define type caster to convert pg array types of above types into @@ -241,3 +243,10 @@ def register_array_to_string_typecasters(connection): _STRING), connection ) + + +def unregister_numeric_typecasters(connection): + string_type_to_decimal = \ + psycopg2.extensions.new_type(TO_STRING_NUMERIC_DATATYPES, + 'TYPECAST_TO_DECIMAL', _DECIMAL) + psycopg2.extensions.register_type(string_type_to_decimal, connection)