diff --git a/CHANGES.txt b/CHANGES.txt index 68ea10ddd7..c23c301c94 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 3.6 + * COPY TO should have higher double precision (CASSANDRA-11255) * Stress should exit with non-zero status after failure (CASSANDRA-10340) * Add client to cqlsh SHOW_SESSION (CASSANDRA-8958) * Fix nodetool tablestats keyspace level metrics (CASSANDRA-11226) diff --git a/bin/cqlsh.py b/bin/cqlsh.py index 3be72b41a7..eb3e579d6a 100644 --- a/bin/cqlsh.py +++ b/bin/cqlsh.py @@ -183,6 +183,7 @@ DEFAULT_CONNECT_TIMEOUT_SECONDS = 5 DEFAULT_REQUEST_TIMEOUT_SECONDS = 10 DEFAULT_FLOAT_PRECISION = 5 +DEFAULT_DOUBLE_PRECISION = 5 DEFAULT_MAX_TRACE_WAIT = 10 if readline is not None and readline.__doc__ is not None and 'libedit' in readline.__doc__: @@ -478,7 +479,8 @@ COPY_COMMON_OPTIONS = ['DELIMITER', 'QUOTE', 'ESCAPE', 'HEADER', 'NULL', 'DATETI 'NUMPROCESSES', 'CONFIGFILE', 'RATEFILE'] COPY_FROM_OPTIONS = ['CHUNKSIZE', 'INGESTRATE', 'MAXBATCHSIZE', 'MINBATCHSIZE', 'MAXROWS', 'SKIPROWS', 'SKIPCOLS', 'MAXPARSEERRORS', 'MAXINSERTERRORS', 'ERRFILE', 'PREPAREDSTATEMENTS', 'TTL'] -COPY_TO_OPTIONS = ['ENCODING', 'PAGESIZE', 'PAGETIMEOUT', 'BEGINTOKEN', 'ENDTOKEN', 'MAXOUTPUTSIZE', 'MAXREQUESTS'] +COPY_TO_OPTIONS = ['ENCODING', 'PAGESIZE', 'PAGETIMEOUT', 'BEGINTOKEN', 'ENDTOKEN', 'MAXOUTPUTSIZE', 'MAXREQUESTS', + 'FLOATPRECISION', 'DOUBLEPRECISION'] @cqlsh_syntax_completer('copyOption', 'optnames') @@ -666,6 +668,7 @@ class Shell(cmd.Cmd): display_timestamp_format=DEFAULT_TIMESTAMP_FORMAT, display_date_format=DEFAULT_DATE_FORMAT, display_float_precision=DEFAULT_FLOAT_PRECISION, + display_double_precision=DEFAULT_DOUBLE_PRECISION, display_timezone=None, max_trace_wait=DEFAULT_MAX_TRACE_WAIT, ssl=False, @@ -715,6 +718,7 @@ class Shell(cmd.Cmd): self.display_date_format = display_date_format self.display_float_precision = display_float_precision + self.display_double_precision = display_double_precision self.display_timezone = display_timezone @@ -798,9 +802,11 @@ class Shell(cmd.Cmd): dtformats = DateTimeFormat(timestamp_format=self.display_timestamp_format, date_format=self.display_date_format, nanotime_format=self.display_nanotime_format, timezone=self.display_timezone) + precision = self.display_double_precision if cqltype is not None and cqltype.type_name == 'double' \ + else self.display_float_precision return format_value(val, cqltype=cqltype, encoding=self.output_codec.name, addcolor=self.color, date_time_format=dtformats, - float_precision=self.display_float_precision, **kwargs) + float_precision=precision, **kwargs) except Exception, e: err = FormatError(val, e) self.decoding_errors.append(err) @@ -1869,6 +1875,8 @@ class Shell(cmd.Cmd): MAXOUTPUTSIZE='-1' - the maximum size of the output file measured in number of lines, beyond this maximum the output file will be split into segments, -1 means unlimited. + FLOATPRECISION=5 - the number of digits displayed after the decimal point for cql float values + DOUBLEPRECISION=12 - the number of digits displayed after the decimal point for cql double values When entering CSV data on STDIN, you can use the sequence "\." on a line by itself to end the data input. @@ -1974,6 +1982,7 @@ class Shell(cmd.Cmd): display_date_format=self.display_date_format, display_nanotime_format=self.display_nanotime_format, display_float_precision=self.display_float_precision, + display_double_precision=self.display_double_precision, max_trace_wait=self.max_trace_wait) subshell.cmdloop() f.close() @@ -2425,6 +2434,8 @@ def read_options(cmdlineargs, environment): DEFAULT_DATE_FORMAT) optvalues.float_precision = option_with_default(configs.getint, 'ui', 'float_precision', DEFAULT_FLOAT_PRECISION) + optvalues.double_precision = option_with_default(configs.getint, 'ui', 'double_precision', + DEFAULT_DOUBLE_PRECISION) optvalues.field_size_limit = option_with_default(configs.getint, 'csv', 'field_size_limit', csv.field_size_limit()) optvalues.max_trace_wait = option_with_default(configs.getfloat, 'tracing', 'max_trace_wait', DEFAULT_MAX_TRACE_WAIT) @@ -2595,6 +2606,7 @@ def main(options, hostname, port): display_nanotime_format=options.nanotime_format, display_date_format=options.date_format, display_float_precision=options.float_precision, + display_double_precision=options.double_precision, display_timezone=timezone, max_trace_wait=options.max_trace_wait, ssl=options.ssl, diff --git a/conf/cqlshrc.sample b/conf/cqlshrc.sample index c55609f014..df9abdf88b 100644 --- a/conf/cqlshrc.sample +++ b/conf/cqlshrc.sample @@ -35,9 +35,10 @@ ;; Display timezone ;timezone = Etc/UTC -;; The number of digits displayed after the decimal point +;; The number of digits displayed after the decimal point for single and double precision numbers ;; (note that increasing this to large numbers can result in unusual values) -; float_precision = 5 +;float_precision = 5 +;double_precision = 12 ;; Used for automatic completion and suggestions ; completekey = tab diff --git a/pylib/cqlshlib/copyutil.py b/pylib/cqlshlib/copyutil.py index ef96a92db9..563a7ba322 100644 --- a/pylib/cqlshlib/copyutil.py +++ b/pylib/cqlshlib/copyutil.py @@ -254,7 +254,8 @@ class CopyTask(object): copy_options['maxattempts'] = int(opts.pop('maxattempts', 5)) copy_options['dtformats'] = DateTimeFormat(opts.pop('datetimeformat', shell.display_timestamp_format), shell.display_date_format, shell.display_nanotime_format) - copy_options['float_precision'] = shell.display_float_precision + copy_options['floatprecision'] = int(opts.pop('floatprecision', '5')) + copy_options['doubleprecision'] = int(opts.pop('doubleprecision', '12')) copy_options['chunksize'] = int(opts.pop('chunksize', 5000)) copy_options['ingestrate'] = int(opts.pop('ingestrate', 100000)) copy_options['maxbatchsize'] = int(opts.pop('maxbatchsize', 20)) @@ -1346,7 +1347,8 @@ class ExportProcess(ChildProcess): ChildProcess.__init__(self, params=params, target=self.run) options = params['options'] self.encoding = options.copy['encoding'] - self.float_precision = options.copy['float_precision'] + self.float_precision = options.copy['floatprecision'] + self.double_precision = options.copy['doubleprecision'] self.nullval = options.copy['nullval'] self.max_requests = options.copy['maxrequests'] @@ -1510,9 +1512,12 @@ class ExportProcess(ChildProcess): formatter = get_formatter(val, cqltype) self.formatters[cqltype] = formatter + if not hasattr(cqltype, 'precision'): + cqltype.precision = self.double_precision if cqltype.type_name == 'double' else self.float_precision + return formatter(val, cqltype=cqltype, encoding=self.encoding, colormap=NO_COLOR_MAP, date_time_format=self.date_time_format, - float_precision=self.float_precision, nullval=self.nullval, quote=False, + float_precision=cqltype.precision, nullval=self.nullval, quote=False, decimal_sep=self.decimal_sep, thousands_sep=self.thousands_sep, boolean_styles=self.boolean_styles)