You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2016/02/02 15:07:56 UTC

cassandra git commit: cqlsh: Include sub-second precision in timestamps by default

Repository: cassandra
Updated Branches:
  refs/heads/trunk b339b60ec -> 27d88ee33


cqlsh: Include sub-second precision in timestamps by default

Patch by Stefania Alborghetti; reviewed by Paulo Motta for CASSANDRA-10428


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/27d88ee3
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/27d88ee3
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/27d88ee3

Branch: refs/heads/trunk
Commit: 27d88ee33506493a115af09857c06593fdd73b07
Parents: b339b60
Author: Stefania Alborghetti <st...@datastax.com>
Authored: Tue Dec 22 16:53:53 2015 +0100
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Tue Feb 2 15:04:57 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                  |  1 +
 bin/cqlsh.py                 | 11 ++++++-----
 pylib/cqlshlib/copyutil.py   | 13 ++++++++-----
 pylib/cqlshlib/formatting.py | 22 +++++++++++-----------
 4 files changed, 26 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/27d88ee3/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index fb73013..56d214c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.4
+ * cqlsh: Include sub-second precision in timestamps by default (CASSANDRA-10428)
  * Set javac encoding to utf-8 (CASSANDRA-11077)
  * Integrate SASI index into Cassandra (CASSANDRA-10661)
  * Add --skip-flush option to nodetool snapshot

http://git-wip-us.apache.org/repos/asf/cassandra/blob/27d88ee3/bin/cqlsh.py
----------------------------------------------------------------------
diff --git a/bin/cqlsh.py b/bin/cqlsh.py
index adc0bbb..dcb90b6 100644
--- a/bin/cqlsh.py
+++ b/bin/cqlsh.py
@@ -52,6 +52,10 @@ from uuid import UUID
 if sys.version_info[0] != 2 or sys.version_info[1] != 7:
     sys.exit("\nCQL Shell supports only Python 2.7\n")
 
+# see CASSANDRA-10428
+if platform.python_implementation().startswith('Jython'):
+    sys.exit("\nCQL Shell does not run on Jython\n")
+
 description = "CQL Shell for Apache Cassandra"
 version = "5.0.1"
 
@@ -723,10 +727,6 @@ class Shell(cmd.Cmd):
 
         self.current_keyspace = keyspace
 
-        self.display_timestamp_format = display_timestamp_format
-        self.display_nanotime_format = display_nanotime_format
-        self.display_date_format = display_date_format
-
         self.max_trace_wait = max_trace_wait
         self.session.max_trace_wait = max_trace_wait
         if encoding is None:
@@ -781,7 +781,8 @@ class Shell(cmd.Cmd):
             self.decoding_errors.append(val)
         try:
             dtformats = DateTimeFormat(timestamp_format=self.display_timestamp_format,
-                                       date_format=self.display_date_format, nanotime_format=self.display_nanotime_format)
+                                       date_format=self.display_date_format,
+                                       nanotime_format=self.display_nanotime_format)
             return format_value(val, self.output_codec.name,
                                 addcolor=self.color, date_time_format=dtformats,
                                 float_precision=self.display_float_precision, **kwargs)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/27d88ee3/pylib/cqlshlib/copyutil.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/copyutil.py b/pylib/cqlshlib/copyutil.py
index 97f1a98..95da679 100644
--- a/pylib/cqlshlib/copyutil.py
+++ b/pylib/cqlshlib/copyutil.py
@@ -1471,9 +1471,9 @@ class ImportConversion(object):
 
             return ret
 
-        # this should match all possible CQL datetime formats
+        # this should match all possible CQL and CQLSH datetime formats
         p = re.compile("(\d{4})\-(\d{2})\-(\d{2})\s?(?:'T')?" +  # YYYY-MM-DD[( |'T')]
-                       "(?:(\d{2}):(\d{2})(?::(\d{2}))?)?" +  # [HH:MM[:SS]]
+                       "(?:(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,6}))?))?" +  # [HH:MM[:SS[.NNNNNN]]]
                        "(?:([+\-])(\d{2}):?(\d{2}))?")  # [(+|-)HH[:]MM]]
 
         def convert_datetime(val, **_):
@@ -1494,13 +1494,16 @@ class ImportConversion(object):
                                     int(m.group(6)) if m.group(6) else 0,  # second
                                     0, 1, -1))  # day of week, day of year, dst-flag
 
-            if m.group(7):
-                offset = (int(m.group(8)) * 3600 + int(m.group(9)) * 60) * int(m.group(7) + '1')
+            # convert sub-seconds (a number between 1 and 6 digits) to milliseconds
+            milliseconds = 0 if not m.group(7) else int(m.group(7)) * pow(10, 3 - len(m.group(7)))
+
+            if m.group(8):
+                offset = (int(m.group(9)) * 3600 + int(m.group(10)) * 60) * int(m.group(8) + '1')
             else:
                 offset = -time.timezone
 
             # scale seconds to millis for the raw value
-            return (timegm(tval) + offset) * 1e3
+            return ((timegm(tval) + offset) * 1e3) + milliseconds
 
         def convert_date(v, **_):
             return Date(v)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/27d88ee3/pylib/cqlshlib/formatting.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/formatting.py b/pylib/cqlshlib/formatting.py
index 2e219c8..ef7e3fd 100644
--- a/pylib/cqlshlib/formatting.py
+++ b/pylib/cqlshlib/formatting.py
@@ -16,7 +16,9 @@
 
 import binascii
 import calendar
+import datetime
 import math
+import os
 import re
 import sys
 import platform
@@ -99,15 +101,16 @@ def color_text(bval, colormap, displaywidth=None):
 
 DEFAULT_NANOTIME_FORMAT = '%H:%M:%S.%N'
 DEFAULT_DATE_FORMAT = '%Y-%m-%d'
-DEFAULT_TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S%z'
 
-if platform.system() == 'Windows':
-    DEFAULT_TIME_FORMAT = '%Y-%m-%d %H:%M:%S %Z'
+DEFAULT_TIMESTAMP_FORMAT = os.environ.get('CQLSH_DEFAULT_TIMESTAMP_FORMAT', '')
+if not DEFAULT_TIMESTAMP_FORMAT:
+    DEFAULT_TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S.%f%z'
 
 
-class DateTimeFormat():
+class DateTimeFormat:
 
-    def __init__(self, timestamp_format=DEFAULT_TIMESTAMP_FORMAT, date_format=DEFAULT_DATE_FORMAT, nanotime_format=DEFAULT_NANOTIME_FORMAT):
+    def __init__(self, timestamp_format=DEFAULT_TIMESTAMP_FORMAT, date_format=DEFAULT_DATE_FORMAT,
+                 nanotime_format=DEFAULT_NANOTIME_FORMAT):
         self.timestamp_format = timestamp_format
         self.date_format = date_format
         self.nanotime_format = nanotime_format
@@ -234,17 +237,14 @@ formatter_for('int')(format_integer_type)
 
 @formatter_for('datetime')
 def format_value_timestamp(val, colormap, date_time_format, quote=False, **_):
-    bval = strftime(date_time_format.timestamp_format, calendar.timegm(val.utctimetuple()))
+    tzless_dt = datetime_from_timestamp(calendar.timegm(val.utctimetuple())) \
+        + datetime.timedelta(microseconds=val.microsecond)
+    bval = tzless_dt.replace(tzinfo=UTC()).strftime(date_time_format.timestamp_format)
     if quote:
         bval = "'%s'" % bval
     return colorme(bval, colormap, 'timestamp')
 
 
-def strftime(time_format, seconds):
-    tzless_dt = datetime_from_timestamp(seconds)
-    return tzless_dt.replace(tzinfo=UTC()).strftime(time_format)
-
-
 @formatter_for('Date')
 def format_value_date(val, colormap, **_):
     return format_python_formatted_type(val, colormap, 'date')