From 70c8a53de4881a3ccbcf5df7a68f44a57b103f12 Mon Sep 17 00:00:00 2001 From: Adam Holmberg Date: Tue, 24 Nov 2015 14:15:05 -0600 Subject: [PATCH] cqlsh: Display milliseconds when datetime overflows patch by Adam Holmberg; reviewed by Paulo Motta for CASSANDRA-10625 --- CHANGES.txt | 1 + bin/cqlsh.py | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index ae9d545113..f0aa996641 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -39,6 +39,7 @@ Merged from 2.1: * Avoid major compaction mixing repaired and unrepaired sstables in DTCS (CASSANDRA-11113) * Make it clear what DTCS timestamp_resolution is used for (CASSANDRA-11041) * (cqlsh) Support timezone conversion using pytz (CASSANDRA-10397) + * (cqlsh) Display milliseconds when datetime overflows (CASSANDRA-10625) 3.0.3 diff --git a/bin/cqlsh.py b/bin/cqlsh.py index 6cc98c35ec..a4dd2530cb 100644 --- a/bin/cqlsh.py +++ b/bin/cqlsh.py @@ -148,10 +148,13 @@ except ImportError, e: from cassandra.auth import PlainTextAuthProvider from cassandra.cluster import Cluster +from cassandra.marshal import int64_unpack from cassandra.metadata import (ColumnMetadata, KeyspaceMetadata, TableMetadata, protect_name, protect_names) from cassandra.policies import WhiteListRoundRobinPolicy from cassandra.query import SimpleStatement, ordered_dict_factory, TraceUnavailable +from cassandra.type_codes import DateType +from cassandra.util import datetime_from_timestamp # cqlsh should run correctly when run out of a Cassandra source tree, # out of an unpacked Cassandra tarball, and after a proper package install. @@ -600,10 +603,24 @@ def insert_driver_hooks(): def extend_cql_deserialization(): - """ - The python driver returns BLOBs as string, but we expect them as bytearrays - """ + # The python driver returns BLOBs as string, but we expect them as bytearrays cassandra.cqltypes.BytesType.deserialize = staticmethod(lambda byts, protocol_version: bytearray(byts)) + + class DateOverFlowWarning(RuntimeWarning): + pass + + # Native datetime types blow up outside of datetime.[MIN|MAX]_YEAR. We will fall back to an int timestamp + def deserialize_date_fallback_int(byts, protocol_version): + timestamp_ms = int64_unpack(byts) + try: + return datetime_from_timestamp(timestamp_ms / 1000.0) + except OverflowError: + warnings.warn(DateOverFlowWarning("Some timestamps are larger than Python datetime can represent. Timestamps are displayed in milliseconds from epoch.")) + return timestamp_ms + + cassandra.cqltypes.DateType.deserialize = staticmethod(deserialize_date_fallback_int) + + # Return cassandra.cqltypes.EMPTY instead of None for empty values cassandra.cqltypes.CassandraType.support_empty_values = True