diff --git a/CHANGES.txt b/CHANGES.txt index a40530a071..e3428a7a85 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -43,7 +43,6 @@ * Fix cassandra-stress so it respects the CL passed in user mode (CASSANDRA-8948) * Fix rare NPE in ColumnDefinition#hasIndexOption() (CASSANDRA-8786) * cassandra-stress reports per-operation statistics, plus misc (CASSANDRA-8769) - * Add SimpleDate (cql date) and Time (cql time) types (CASSANDRA-7523) * Use long for key count in cfstats (CASSANDRA-8913) * Make SSTableRewriter.abort() more robust to failure (CASSANDRA-8832) * Remove cold_reads_to_omit from STCS (CASSANDRA-8860) diff --git a/NEWS.txt b/NEWS.txt index 081660287e..6610d15cf5 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -21,16 +21,11 @@ Upgrading removed - it is almost always better to use date tiered compaction for workloads that have cold data. -New features ------------- - - New `SimpleDateType` (cql date). 4-byte unsigned integer w/out timestamp - - New `TimeType` (cql time). 8-byte long nano-second resolution timestamp 2.1.4 ===== The default JMX config now listens to localhost only. You must enable the other JMX flags in cassandra-env.sh manually. - 2.1.3 ===== diff --git a/bin/cqlsh b/bin/cqlsh index bd72a4a966..e1bd31210e 100755 --- a/bin/cqlsh +++ b/bin/cqlsh @@ -126,10 +126,6 @@ from cqlshlib.displaying import (RED, BLUE, CYAN, ANSI_RESET, COLUMN_NAME_COLORS FormattedValue, colorme) from cqlshlib.formatting import format_by_type, formatter_for, format_value_utype from cqlshlib.util import trim_if_present, get_file_encoding_bomsize -from cqlshlib.formatting import DateTimeFormat -from cqlshlib.formatting import DEFAULT_TIMESTAMP_FORMAT -from cqlshlib.formatting import DEFAULT_DATE_FORMAT -from cqlshlib.formatting import DEFAULT_NANOTIME_FORMAT from cqlshlib.tracing import print_trace_session, print_trace DEFAULT_HOST = '127.0.0.1' @@ -137,6 +133,7 @@ DEFAULT_PORT = 9042 DEFAULT_CQLVER = '3.2.0' DEFAULT_PROTOCOL_VERSION = 3 +DEFAULT_TIME_FORMAT = '%Y-%m-%d %H:%M:%S%z' DEFAULT_FLOAT_PRECISION = 5 DEFAULT_MAX_TRACE_WAIT = 10 @@ -438,7 +435,7 @@ def full_cql_version(ver): vertuple = tuple(map(int, ver_parts[0].split('.')) + [ver_parts[1]]) return ver, vertuple -def format_value(val, output_encoding, addcolor=False, date_time_format=None, +def format_value(val, output_encoding, addcolor=False, time_format=None, float_precision=None, colormap=None, nullval=None): if isinstance(val, DecodeError): if addcolor: @@ -446,7 +443,7 @@ def format_value(val, output_encoding, addcolor=False, date_time_format=None, else: return FormattedValue(repr(val.thebytes)) return format_by_type(type(val), val, output_encoding, colormap=colormap, - addcolor=addcolor, nullval=nullval, date_time_format=date_time_format, + addcolor=addcolor, nullval=nullval, time_format=time_format, float_precision=float_precision) def show_warning_without_quoting_line(message, category, filename, lineno, file=None, line=None): @@ -536,9 +533,7 @@ class Shell(cmd.Cmd): completekey=DEFAULT_COMPLETEKEY, use_conn=None, cqlver=DEFAULT_CQLVER, keyspace=None, tracing_enabled=False, expand_enabled=False, - display_nanotime_format=DEFAULT_NANOTIME_FORMAT, - display_timestamp_format=DEFAULT_TIMESTAMP_FORMAT, - display_date_format=DEFAULT_DATE_FORMAT, + display_time_format=DEFAULT_TIME_FORMAT, display_float_precision=DEFAULT_FLOAT_PRECISION, max_trace_wait=DEFAULT_MAX_TRACE_WAIT, ssl=False, @@ -574,11 +569,7 @@ class Shell(cmd.Cmd): self.session = self.conn.connect() self.color = color - - self.display_nanotime_format = display_nanotime_format - self.display_timestamp_format = display_timestamp_format - self.display_date_format = display_date_format - + self.display_time_format = display_time_format self.display_float_precision = display_float_precision # Workaround for CASSANDRA-8521 until PYTHON-205 is resolved. @@ -602,10 +593,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: @@ -652,10 +639,8 @@ class Shell(cmd.Cmd): if isinstance(val, DecodeError): 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) return format_value(val, self.output_codec.name, - addcolor=self.color, date_time_format=dtformats, + addcolor=self.color, time_format=self.display_time_format, float_precision=self.display_float_precision, **kwargs) except Exception, e: err = FormatError(val, e) @@ -1717,7 +1702,7 @@ class Shell(cmd.Cmd): return 0 wmeter = meter.Meter() try: - dtformats = DateTimeFormat(self.display_timestamp_format, self.display_date_format, self.display_nanotime_format) + dump = self.prep_export_dump(ks, cf, columns) writer = csv.writer(csvdest, **dialect_options) if header: @@ -1725,7 +1710,7 @@ class Shell(cmd.Cmd): for row in dump: fmt = lambda v: \ format_value(v, output_encoding=encoding, nullval=nullval, - date_time_format=dtformats, + time_format=self.display_time_format, float_precision=self.display_float_precision).strval writer.writerow(map(fmt, row.values())) wmeter.mark_written() @@ -1807,9 +1792,7 @@ class Shell(cmd.Cmd): subshell = Shell(self.hostname, self.port, color=self.color, encoding=self.encoding, stdin=f, tty=False, use_conn=self.conn, cqlver=self.cql_version, - display_timestamp_format=self.display_timestamp_format, - display_date_format=self.display_date_format, - display_nanotime_format=self.display_nanotime_format, + display_time_format=self.display_time_format, display_float_precision=self.display_float_precision, max_trace_wait=self.max_trace_wait) subshell.cmdloop() @@ -2117,11 +2100,7 @@ def read_options(cmdlineargs, environment): DEFAULT_COMPLETEKEY) optvalues.color = option_with_default(configs.getboolean, 'ui', 'color') optvalues.time_format = raw_option_with_default(configs, 'ui', 'time_format', - DEFAULT_TIMESTAMP_FORMAT) - optvalues.nanotime_format = raw_option_with_default(configs, 'ui', 'nanotime_format', - DEFAULT_NANOTIME_FORMAT) - optvalues.date_format = raw_option_with_default(configs, 'ui', 'date_format', - DEFAULT_DATE_FORMAT) + DEFAULT_TIME_FORMAT) optvalues.float_precision = option_with_default(configs.getint, 'ui', 'float_precision', DEFAULT_FLOAT_PRECISION) optvalues.field_size_limit = option_with_default(configs.getint, 'csv', 'field_size_limit', csv.field_size_limit()) @@ -2241,9 +2220,7 @@ def main(options, hostname, port): completekey=options.completekey, cqlver=options.cqlversion, keyspace=options.keyspace, - display_timestamp_format=options.time_format, - display_nanotime_format=options.nanotime_format, - display_date_format=options.date_format, + display_time_format=options.time_format, display_float_precision=options.float_precision, max_trace_wait=options.max_trace_wait, ssl=options.ssl, diff --git a/doc/cql3/CQL.textile b/doc/cql3/CQL.textile index 0c09b3230e..0221bc12f7 100644 --- a/doc/cql3/CQL.textile +++ b/doc/cql3/CQL.textile @@ -944,14 +944,12 @@ bc(syntax).. | blob | boolean | counter - | date | decimal | double | float | inet | int | text - | time | timestamp | timeuuid | uuid @@ -972,15 +970,13 @@ p. The following table gives additional informations on the native data types, a |@blob@ | blobs |Arbitrary bytes (no validation)| |@boolean@ | booleans |true or false| |@counter@ | integers |Counter column (64-bit signed value). See "Counters":#counters for details| -|@date@ | integers, strings |A date (with no corresponding time value). See "Working with dates":#usingdates below for more information.| |@decimal@ | integers, floats |Variable-precision decimal| |@double@ | integers |64-bit IEEE-754 floating point| |@float@ | integers, floats |32-bit IEEE-754 floating point| |@inet@ | strings |An IP address. It can be either 4 bytes long (IPv4) or 16 bytes long (IPv6). There is no @inet@ constant, IP address should be inputed as strings| |@int@ | integers |32-bit signed int| |@text@ | strings |UTF8 encoded string| -|@time@ | integers, strings |A time with nanosecond precision. See "Working with time":#usingtime below for more information.| -|@timestamp@| integers, strings |A timestamp. Strings constant are allow to input timestamps as dates, see "Working with timestamps":#usingtimestamps below for more information.| +|@timestamp@| integers, strings |A timestamp. Strings constant are allow to input timestamps as dates, see "Working with dates":#usingdates below for more information.| |@timeuuid@ | uuids |Type 1 UUID. This is generally used as a "conflict-free" timestamp. Also see the "functions on Timeuuid":#timeuuidFun| |@uuid@ | uuids |Type 1 or type 4 UUID| |@varchar@ | strings |UTF8 encoded string| @@ -988,7 +984,7 @@ p. The following table gives additional informations on the native data types, a For more information on how to use the collection types, see the "Working with collections":#collections section below. -h3(#usingtimestamps). Working with timestamps +h3(#usingdates). Working with dates Values of the @timestamp@ type are encoded as 64-bit signed integers representing a number of milliseconds since the standard base time known as "the epoch": January 1 1970 at 00:00:00 GMT. @@ -1022,31 +1018,6 @@ The time of day may also be omitted, if the date is the only piece that matters: In that case, the time of day will default to 00:00:00, in the specified or default time zone. -h3(#usingdates). Working with dates - -Values of the @date@ type are encoded as 32-bit unsigned integers representing a number of days with "the epoch" at the center of the range (2^31). Epoch is January 1st, 1970 - -A date can be input in CQL as an unsigned integer as defined above. - -They can also be input as string literals in the following format: - -* @2014-01-01@ - - -h3(#usingtime). Working with time - -Values of the @time@ type are encoded as 64-bit signed integers representing the number of nanoseconds since midnight. - -A time can be input in CQL as simple long integers, giving the number of nanoseconds since midnight. - -They can also be input as string literals in any of the following formats: - -* @08:12:54@ -* @08:12:54.123@ -* @08:12:54.123456@ -* @08:12:54.123456789@ - - h3(#counters). Counters The @counter@ type is used to define _counter columns_. A counter column is a column whose value is a 64-bit signed integer and on which 2 operations are supported: incrementation and decrementation (see "@UPDATE@":#updateStmt for syntax). Note the value of a counter cannot be set. A counter doesn't exist until first incremented/decremented, and the first incrementation/decrementation is made as if the previous value was 0. Deletion of counter columns is supported but have some limitations (see the "Cassandra Wiki":http://wiki.apache.org/cassandra/Counters for more information). @@ -1211,7 +1182,7 @@ will never return any result by design, since the value returned by @now()@ is g h4. @minTimeuuid@ and @maxTimeuuid@ -The @minTimeuuid@ (resp. @maxTimeuuid@) function takes a @timestamp@ value @t@ (which can be "either a timestamp or a date string":#usingtimestamps) and return a _fake_ @timeuuid@ corresponding to the _smallest_ (resp. _biggest_) possible @timeuuid@ having for timestamp @t@. So for instance: +The @minTimeuuid@ (resp. @maxTimeuuid@) function takes a @timestamp@ value @t@ (which can be "either a timestamp or a date string":#usingdates) and return a _fake_ @timeuuid@ corresponding to the _smallest_ (resp. _biggest_) possible @timeuuid@ having for timestamp @t@. So for instance: bc(sample). SELECT * FROM myTable WHERE t > maxTimeuuid('2013-01-01 00:05+0000') AND t < minTimeuuid('2013-02-02 10:00+0000') @@ -1319,8 +1290,6 @@ CQL distinguishes between _reserved_ and _non-reserved_ keywords. Reserved keywo | @WITH@ | yes | | @WRITETIME@ | no | | @DISTINCT@ | no | -| @DATE@ | no | -| @TIME@ | no | h2(#appendixB). Appendix B: CQL Reserved Types @@ -1369,7 +1338,7 @@ h3. 3.1.4 h3. 3.1.3 -* Millisecond precision formats have been added to the timestamp parser (see "working with dates":#usingtimestamps). +* Millisecond precision formats have been added to the timestamp parser (see "working with dates":#usingdates). h3. 3.1.2 @@ -1409,7 +1378,7 @@ h3. 3.0.2 h3. 3.0.1 -* "Date strings":#usingtimestamps (and timestamps) are no longer accepted as valid @timeuuid@ values. Doing so was a bug in the sense that date string are not valid @timeuuid@, and it was thus resulting in "confusing behaviors":https://issues.apache.org/jira/browse/CASSANDRA-4936. However, the following new methods have been added to help working with @timeuuid@: @now@, @minTimeuuid@, @maxTimeuuid@ , @dateOf@ and @unixTimestampOf@. See the "section dedicated to these methods":#usingtimeuuid for more detail. +* "Date strings":#usingdates (and timestamps) are no longer accepted as valid @timeuuid@ values. Doing so was a bug in the sense that date string are not valid @timeuuid@, and it was thus resulting in "confusing behaviors":https://issues.apache.org/jira/browse/CASSANDRA-4936. However, the following new methods have been added to help working with @timeuuid@: @now@, @minTimeuuid@, @maxTimeuuid@ , @dateOf@ and @unixTimestampOf@. See the "section dedicated to these methods":#usingtimeuuid for more detail. * "Float constants"#constants now support the exponent notation. In other words, @4.2E10@ is now a valid floating point value. diff --git a/lib/joda-time-2.4.jar b/lib/joda-time-2.4.jar deleted file mode 100644 index ace67d7a25..0000000000 Binary files a/lib/joda-time-2.4.jar and /dev/null differ diff --git a/lib/licenses/joda-time-2.4.txt b/lib/licenses/joda-time-2.4.txt deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/lib/licenses/joda-time-2.4.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py index 0da6a7ccc6..88f042ec6e 100644 --- a/pylib/cqlshlib/cql3handling.py +++ b/pylib/cqlshlib/cql3handling.py @@ -19,8 +19,8 @@ from cassandra.metadata import maybe_escape_name from cassandra.metadata import escape_name -simple_cql_types = set(('ascii', 'bigint', 'blob', 'boolean', 'counter', 'date', 'decimal', 'double', 'float', 'inet', 'int', - 'text', 'time', 'timestamp', 'timeuuid', 'uuid', 'varchar', 'varint')) +simple_cql_types = set(('ascii', 'bigint', 'blob', 'boolean', 'counter', 'decimal', 'double', 'float', 'inet', 'int', + 'text', 'timestamp', 'timeuuid', 'uuid', 'varchar', 'varint')) simple_cql_types.difference_update(('set', 'map', 'list')) from . import helptopics @@ -42,7 +42,7 @@ class Cql3ParsingRuleSet(CqlParsingRuleSet): 'limit', 'using', 'use', 'count', 'set', 'begin', 'apply', 'batch', 'truncate', 'delete', 'in', 'create', 'keyspace', 'schema', 'columnfamily', 'table', 'index', 'on', 'drop', - 'primary', 'into', 'values', 'date', 'time', 'timestamp', 'ttl', 'alter', 'add', 'type', + 'primary', 'into', 'values', 'timestamp', 'ttl', 'alter', 'add', 'type', 'compact', 'storage', 'order', 'by', 'asc', 'desc', 'clustering', 'token', 'writetime', 'map', 'list', 'to', 'custom', 'if', 'not' )) diff --git a/pylib/cqlshlib/displaying.py b/pylib/cqlshlib/displaying.py index 0cac30911a..13e3cf465b 100644 --- a/pylib/cqlshlib/displaying.py +++ b/pylib/cqlshlib/displaying.py @@ -95,8 +95,6 @@ DEFAULT_VALUE_COLORS = dict( error=RED, blob=DARK_MAGENTA, timestamp=GREEN, - date=GREEN, - time=GREEN, int=GREEN, float=GREEN, decimal=GREEN, diff --git a/pylib/cqlshlib/formatting.py b/pylib/cqlshlib/formatting.py index 868ec289de..e9d22fda4d 100644 --- a/pylib/cqlshlib/formatting.py +++ b/pylib/cqlshlib/formatting.py @@ -14,15 +14,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -import calendar -import math import re import time -import sys +import calendar +import math from collections import defaultdict from . import wcwidth from .displaying import colorme, FormattedValue, DEFAULT_VALUE_COLORS -from datetime import datetime, timedelta from cassandra.cqltypes import EMPTY unicode_controlchars_re = re.compile(r'[\x00-\x31\x7f-\xa0]') @@ -47,12 +45,13 @@ def _make_turn_bits_red_f(color1, color2): return _turn_bits_red default_null_placeholder = 'null' +default_time_format = '' default_float_precision = 3 default_colormap = DEFAULT_VALUE_COLORS empty_colormap = defaultdict(lambda: '') def format_by_type(cqltype, val, encoding, colormap=None, addcolor=False, - nullval=None, date_time_format=None, float_precision=None): + nullval=None, time_format=None, float_precision=None): if nullval is None: nullval = default_null_placeholder if val is None: @@ -61,12 +60,12 @@ def format_by_type(cqltype, val, encoding, colormap=None, addcolor=False, colormap = empty_colormap elif colormap is None: colormap = default_colormap - if date_time_format is None: - date_time_format = DateTimeFormat() + if time_format is None: + time_format = default_time_format if float_precision is None: float_precision = default_float_precision return format_value(cqltype, val, encoding=encoding, colormap=colormap, - date_time_format=date_time_format, float_precision=float_precision, + time_format=time_format, float_precision=float_precision, nullval=nullval) def color_text(bval, colormap, displaywidth=None): @@ -87,16 +86,6 @@ def color_text(bval, colormap, displaywidth=None): displaywidth -= bval.count(r'\\') return FormattedValue(bval, coloredval, displaywidth) -DEFAULT_NANOTIME_FORMAT = '%H:%M:%S.%N' -DEFAULT_DATE_FORMAT = '%Y-%m-%d' -DEFAULT_TIMESTAMP_FORMAT = '%Y-%m-%d %H:%M:%S%z' - -class DateTimeFormat(): - 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 - def format_value_default(val, colormap, **_): val = str(val) escapedval = val.replace('\\', '\\\\') @@ -168,13 +157,15 @@ def format_integer_type(val, colormap, **_): formatter_for('long')(format_integer_type) 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())) +@formatter_for('date') +def format_value_timestamp(val, colormap, time_format, quote=False, **_): + bval = strftime(time_format, calendar.timegm(val.utctimetuple())) if quote: bval = "'%s'" % bval return colorme(bval, colormap, 'timestamp') +formatter_for('datetime')(format_value_timestamp) + def strftime(time_format, seconds): local = time.localtime(seconds) formatted = time.strftime(time_format, local) @@ -192,14 +183,6 @@ def strftime(time_format, seconds): hours, minutes = divmod(abs(offset) / 60, 60) return formatted[:-5] + sign + '{0:0=2}{1:0=2}'.format(hours, minutes) -@formatter_for('date') -def format_value_uuid(val, colormap, **_): - return format_python_formatted_type(val, colormap, 'date') - -@formatter_for('Time') -def format_value_time(val, colormap, **_): - return format_python_formatted_type(val, colormap, 'time') - @formatter_for('str') def format_value_text(val, encoding, colormap, quote=False, **_): escapedval = val.replace(u'\\', u'\\\\') @@ -216,9 +199,9 @@ def format_value_text(val, encoding, colormap, quote=False, **_): formatter_for('unicode')(format_value_text) def format_simple_collection(val, lbracket, rbracket, encoding, - colormap, date_time_format, float_precision, nullval): + colormap, time_format, float_precision, nullval): subs = [format_value(type(sval), sval, encoding=encoding, colormap=colormap, - date_time_format=date_time_format, float_precision=float_precision, + time_format=time_format, float_precision=float_precision, nullval=nullval, quote=True) for sval in val] bval = lbracket + ', '.join(sval.strval for sval in subs) + rbracket @@ -229,28 +212,28 @@ def format_simple_collection(val, lbracket, rbracket, encoding, return FormattedValue(bval, coloredval, displaywidth) @formatter_for('list') -def format_value_list(val, encoding, colormap, date_time_format, float_precision, nullval, **_): +def format_value_list(val, encoding, colormap, time_format, float_precision, nullval, **_): return format_simple_collection(val, '[', ']', encoding, colormap, - date_time_format, float_precision, nullval) + time_format, float_precision, nullval) @formatter_for('tuple') -def format_value_tuple(val, encoding, colormap, date_time_format, float_precision, nullval, **_): +def format_value_tuple(val, encoding, colormap, time_format, float_precision, nullval, **_): return format_simple_collection(val, '(', ')', encoding, colormap, - date_time_format, float_precision, nullval) + time_format, float_precision, nullval) @formatter_for('set') -def format_value_set(val, encoding, colormap, date_time_format, float_precision, nullval, **_): +def format_value_set(val, encoding, colormap, time_format, float_precision, nullval, **_): return format_simple_collection(sorted(val), '{', '}', encoding, colormap, - date_time_format, float_precision, nullval) + time_format, float_precision, nullval) formatter_for('frozenset')(format_value_set) formatter_for('sortedset')(format_value_set) @formatter_for('dict') -def format_value_map(val, encoding, colormap, date_time_format, float_precision, nullval, **_): +def format_value_map(val, encoding, colormap, time_format, float_precision, nullval, **_): def subformat(v): return format_value(type(v), v, encoding=encoding, colormap=colormap, - date_time_format=date_time_format, float_precision=float_precision, + time_format=time_format, float_precision=float_precision, nullval=nullval, quote=True) subs = [(subformat(k), subformat(v)) for (k, v) in sorted(val.items())] @@ -267,12 +250,12 @@ formatter_for('OrderedMap')(format_value_map) formatter_for('OrderedMapSerializedKey')(format_value_map) -def format_value_utype(val, encoding, colormap, date_time_format, float_precision, nullval, **_): +def format_value_utype(val, encoding, colormap, time_format, float_precision, nullval, **_): def format_field_value(v): if v is None: return colorme(nullval, colormap, 'error') return format_value(type(v), v, encoding=encoding, colormap=colormap, - date_time_format=date_time_format, float_precision=float_precision, + time_format=time_format, float_precision=float_precision, nullval=nullval, quote=True) def format_field_name(name): diff --git a/pylib/cqlshlib/helptopics.py b/pylib/cqlshlib/helptopics.py index 65918baef9..bb5b382f54 100644 --- a/pylib/cqlshlib/helptopics.py +++ b/pylib/cqlshlib/helptopics.py @@ -33,8 +33,6 @@ class CQLHelpTopics(object): one of the following topics: HELP TIMESTAMP_INPUT - HELP DATE_INPUT - HELP TIME_INPUT HELP BLOB_INPUT HELP UUID_INPUT HELP BOOLEAN_INPUT @@ -71,27 +69,6 @@ class CQLHelpTopics(object): server node will be used. """ - def help_date_input(self): - print """ - Date input - - CQL supports the following format for date specification: - - yyyy-mm-dd - """ - - def help_time_input(self): - print """ - Time input - - CQL supports the following format for time specification: - - HH:MM:SS - HH:MM:SS.mmm - HH:MM:SS.mmmuuu - HH:MM:SS.mmmuuunnn - """ - def help_blob_input(self): print """ Blob input diff --git a/pylib/cqlshlib/test/test_cqlsh_output.py b/pylib/cqlshlib/test/test_cqlsh_output.py index 7a7ed890ca..60ef3a4c68 100644 --- a/pylib/cqlshlib/test/test_cqlsh_output.py +++ b/pylib/cqlshlib/test/test_cqlsh_output.py @@ -113,11 +113,10 @@ class TestCqlshOutput(BaseTestCase): self.assertTrue(6 <= len(output) <= 8, msg='output: %r' % '\n'.join(output)) self.assertEqual(output[0], '') - self.assertEqual(output[1], 'Warning! Non-ISO 8601 dates detected (< 1-1-1 or > 9999-12-31). Returning raw days since epoch.'); - self.assertNicelyFormattedTableHeader(output[2]) - self.assertNicelyFormattedTableRule(output[3]) - self.assertNicelyFormattedTableData(output[4]) - self.assertEqual(output[5].strip(), '') + self.assertNicelyFormattedTableHeader(output[1]) + self.assertNicelyFormattedTableRule(output[2]) + self.assertNicelyFormattedTableData(output[3]) + self.assertEqual(output[4].strip(), '') def test_color_output(self): for termname in ('xterm', 'unknown-garbage'): @@ -275,9 +274,9 @@ class TestCqlshOutput(BaseTestCase): # same query should show up as empty in cql 3 self.assertQueriesGiveColoredOutput(( (q, """ - num | asciicol | bigintcol | blobcol | booleancol | datecol | decimalcol | doublecol | floatcol | intcol | textcol | timecol | timestampcol | uuidcol | varcharcol | varintcol - RRR MMMMMMMM MMMMMMMMM MMMMMMM MMMMMMMMMM MMMMMMM MMMMMMMMMM MMMMMMMMM MMMMMMMM MMMMMM MMMMMMM MMMMMMM MMMMMMMMMMMM MMMMMMM MMMMMMMMMM MMMMMMMMM - -----+----------+-----------+---------+------------+---------+------------+-----------+----------+--------+---------+---------+--------------+---------+------------+----------- + num | asciicol | bigintcol | blobcol | booleancol | decimalcol | doublecol | floatcol | intcol | textcol | timestampcol | uuidcol | varcharcol | varintcol + RRR MMMMMMMM MMMMMMMMM MMMMMMM MMMMMMMMMM MMMMMMMMMM MMMMMMMMM MMMMMMMM MMMMMM MMMMMMM MMMMMMMMMMMM MMMMMMM MMMMMMMMMM MMMMMMMMM + -----+----------+-----------+---------+------------+------------+-----------+----------+--------+---------+--------------+---------+------------+----------- (0 rows) @@ -598,13 +597,11 @@ class TestCqlshOutput(BaseTestCase): bigintcol bigint, blobcol blob, booleancol boolean, - datecol date, decimalcol decimal, doublecol double, floatcol float, intcol int, textcol text, - timecol time, timestampcol timestamp, uuidcol uuid, varcharcol text, diff --git a/pylib/cqlshlib/test/test_keyspace_init.cql b/pylib/cqlshlib/test/test_keyspace_init.cql index 542721aa67..cd5ac75a13 100644 --- a/pylib/cqlshlib/test/test_keyspace_init.cql +++ b/pylib/cqlshlib/test/test_keyspace_init.cql @@ -19,38 +19,37 @@ INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol decimalcol, doublecol, floatcol, textcol, timestampcol, uuidcol, varcharcol, varintcol) VALUES (0, -12, 'abcdefg', 1234567890123456789, 0x000102030405fffefd, true, - 19952.11882, 1.0, -2.1, 'Voilá!', - '2012-05-14 12:53:20+0000', bd1924e1-6af8-44ae-b5e1-f24131dbd460, '"', 10000000000000000000000000); + 19952.11882, 1.0, -2.1, 'Voilá!', '2012-05-14 12:53:20+0000', + bd1924e1-6af8-44ae-b5e1-f24131dbd460, '"', 10000000000000000000000000); INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol, decimalcol, doublecol, floatcol, textcol, timestampcol, uuidcol, varcharcol, varintcol) VALUES (1, 2147483647, '__!''$#@!~"', 9223372036854775807, 0xffffffffffffffffff, true, - 0.00000000000001, 9999999.999, 99999.99, '∭Ƕ⑮ฑ➳❏''', - '1900-01-01+0000', ffffffff-ffff-ffff-ffff-ffffffffffff, 'newline-> + 0.00000000000001, 9999999.999, 99999.99, '∭Ƕ⑮ฑ➳❏''', '1900-01-01+0000', + ffffffff-ffff-ffff-ffff-ffffffffffff, 'newline-> <-', 9); INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol, decimalcol, doublecol, floatcol, textcol, timestampcol, uuidcol, varcharcol, varintcol) VALUES (2, 0, '', 0, 0x, false, - 0.0, 0.0, 0.0, '', - 0, 00000000-0000-0000-0000-000000000000, '', 0); + 0.0, 0.0, 0.0, '', 0, + 00000000-0000-0000-0000-000000000000, '', 0); INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol, decimalcol, doublecol, floatcol, textcol, timestampcol, uuidcol, varcharcol, varintcol) VALUES (3, -2147483648, '''''''', -9223372036854775808, 0x80, false, - 10.0000000000000, -1004.10, 100000000.9, '龍馭鬱', - '2038-01-19T03:14-1200', ffffffff-ffff-1fff-8fff-ffffffffffff, - '''', -10000000000000000000000000); + 10.0000000000000, -1004.10, 100000000.9, '龍馭鬱', '2038-01-19T03:14-1200', + ffffffff-ffff-1fff-8fff-ffffffffffff, '''', -10000000000000000000000000); INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol, decimalcol, doublecol, floatcol, textcol, timestampcol, uuidcol, varcharcol, varintcol) -VALUES (4, blobAsInt(0x), '', blobAsBigint(0x), 0x, blobAsBoolean(0x), - blobAsDecimal(0x), blobAsDouble(0x), blobAsFloat(0x), '', - blobAsTimestamp(0x), blobAsUuid(0x), '', blobAsVarint(0x)); +VALUES (4, blobAsInt(0x), '', blobAsBigint(0x), 0x, blobAsBoolean(0x), blobAsDecimal(0x), + blobAsDouble(0x), blobAsFloat(0x), '', blobAsTimestamp(0x), blobAsUuid(0x), '', + blobAsVarint(0x)); diff --git a/src/java/org/apache/cassandra/cql3/CQL3Type.java b/src/java/org/apache/cassandra/cql3/CQL3Type.java index 5fc518d9cd..b656de8a21 100644 --- a/src/java/org/apache/cassandra/cql3/CQL3Type.java +++ b/src/java/org/apache/cassandra/cql3/CQL3Type.java @@ -38,24 +38,22 @@ public interface CQL3Type public enum Native implements CQL3Type { - ASCII (AsciiType.instance), - BIGINT (LongType.instance), - BLOB (BytesType.instance), - BOOLEAN (BooleanType.instance), - COUNTER (CounterColumnType.instance), - DECIMAL (DecimalType.instance), - DOUBLE (DoubleType.instance), - FLOAT (FloatType.instance), - INET (InetAddressType.instance), - INT (Int32Type.instance), - TEXT (UTF8Type.instance), - TIMESTAMP (TimestampType.instance), - UUID (UUIDType.instance), - VARCHAR (UTF8Type.instance), - VARINT (IntegerType.instance), - TIMEUUID (TimeUUIDType.instance), - DATE (SimpleDateType.instance), - TIME (TimeType.instance); + ASCII (AsciiType.instance), + BIGINT (LongType.instance), + BLOB (BytesType.instance), + BOOLEAN (BooleanType.instance), + COUNTER (CounterColumnType.instance), + DECIMAL (DecimalType.instance), + DOUBLE (DoubleType.instance), + FLOAT (FloatType.instance), + INET (InetAddressType.instance), + INT (Int32Type.instance), + TEXT (UTF8Type.instance), + TIMESTAMP(TimestampType.instance), + UUID (UUIDType.instance), + VARCHAR (UTF8Type.instance), + VARINT (IntegerType.instance), + TIMEUUID (TimeUUIDType.instance); private final AbstractType type; diff --git a/src/java/org/apache/cassandra/cql3/Constants.java b/src/java/org/apache/cassandra/cql3/Constants.java index 2d5fdaa51c..01fbdf0459 100644 --- a/src/java/org/apache/cassandra/cql3/Constants.java +++ b/src/java/org/apache/cassandra/cql3/Constants.java @@ -44,7 +44,7 @@ public abstract class Constants public enum Type { - STRING, INTEGER, UUID, FLOAT, DATE, TIME, BOOLEAN, HEX; + STRING, INTEGER, UUID, FLOAT, BOOLEAN, HEX; } public static final Term.Raw NULL_LITERAL = new Term.Raw() @@ -179,8 +179,6 @@ public abstract class Constants case TEXT: case INET: case VARCHAR: - case DATE: - case TIME: case TIMESTAMP: return true; } @@ -190,7 +188,6 @@ public abstract class Constants { case BIGINT: case COUNTER: - case DATE: case DECIMAL: case DOUBLE: case FLOAT: diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g index b7d1b09d7a..f9a07b3d2e 100644 --- a/src/java/org/apache/cassandra/cql3/Cql.g +++ b/src/java/org/apache/cassandra/cql3/Cql.g @@ -1161,8 +1161,6 @@ native_type returns [CQL3Type t] | K_VARCHAR { $t = CQL3Type.Native.VARCHAR; } | K_VARINT { $t = CQL3Type.Native.VARINT; } | K_TIMEUUID { $t = CQL3Type.Native.TIMEUUID; } - | K_DATE { $t = CQL3Type.Native.DATE; } - | K_TIME { $t = CQL3Type.Native.TIME; } ; collection_type returns [CQL3Type.Raw pt] @@ -1330,8 +1328,6 @@ K_VARINT: V A R I N T; K_TIMEUUID: T I M E U U I D; K_TOKEN: T O K E N; K_WRITETIME: W R I T E T I M E; -K_DATE: D A T E; -K_TIME: T I M E; K_NULL: N U L L; K_NOT: N O T; diff --git a/src/java/org/apache/cassandra/db/marshal/IntegerType.java b/src/java/org/apache/cassandra/db/marshal/IntegerType.java index 6da8d39157..ec1c7ad46e 100644 --- a/src/java/org/apache/cassandra/db/marshal/IntegerType.java +++ b/src/java/org/apache/cassandra/db/marshal/IntegerType.java @@ -59,11 +59,6 @@ public final class IntegerType extends AbstractType IntegerType() {/* singleton */} public int compare(ByteBuffer lhs, ByteBuffer rhs) - { - return IntegerType.compareIntegers(lhs, rhs); - } - - public static int compareIntegers(ByteBuffer lhs, ByteBuffer rhs) { int lhsLen = lhs.remaining(); int rhsLen = rhs.remaining(); diff --git a/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java b/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java deleted file mode 100644 index 1dbcf0385a..0000000000 --- a/src/java/org/apache/cassandra/db/marshal/SimpleDateType.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.db.marshal; - -import java.nio.ByteBuffer; - -import org.apache.cassandra.cql3.CQL3Type; -import org.apache.cassandra.serializers.MarshalException; -import org.apache.cassandra.serializers.SimpleDateSerializer; -import org.apache.cassandra.serializers.TypeSerializer; -import org.apache.cassandra.utils.ByteBufferUtil; - -public class SimpleDateType extends AbstractType -{ - public static final SimpleDateType instance = new SimpleDateType(); - - SimpleDateType() {} // singleton - - public int compare(ByteBuffer o1, ByteBuffer o2) - { - // We add Integer.MIN_VALUE to overflow to allow unsigned comparison - return ByteBufferUtil.compareUnsigned(o1, o2); - } - - public boolean isByteOrderComparable() - { - return true; - } - - public ByteBuffer fromString(String source) throws MarshalException - { - return ByteBufferUtil.bytes(SimpleDateSerializer.dateStringToDays(source)); - } - - @Override - public boolean isCompatibleWith(AbstractType previous) - { - return super.isCompatibleWith(previous); - } - - @Override - public boolean isValueCompatibleWithInternal(AbstractType otherType) - { - return this == otherType || otherType == IntegerType.instance; - } - - @Override - public CQL3Type asCQL3Type() - { - return CQL3Type.Native.DATE; - } - - public TypeSerializer getSerializer() - { - return SimpleDateSerializer.instance; - } -} diff --git a/src/java/org/apache/cassandra/db/marshal/TimeType.java b/src/java/org/apache/cassandra/db/marshal/TimeType.java deleted file mode 100644 index b9a0076473..0000000000 --- a/src/java/org/apache/cassandra/db/marshal/TimeType.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.db.marshal; - -import java.nio.ByteBuffer; - -import org.apache.cassandra.serializers.TimeSerializer; -import org.apache.cassandra.cql3.CQL3Type; -import org.apache.cassandra.serializers.TypeSerializer; -import org.apache.cassandra.serializers.MarshalException; -import org.apache.cassandra.utils.ByteBufferUtil; - -/** - * Nanosecond resolution time values - */ -public class TimeType extends AbstractType -{ - public static final TimeType instance = new TimeType(); - private TimeType() {} // singleton - - public int compare(ByteBuffer o1, ByteBuffer o2) - { - return ByteBufferUtil.compareUnsigned(o1, o2); - } - - public ByteBuffer fromString(String source) throws MarshalException - { - return decompose(TimeSerializer.timeStringToLong(source)); - } - - public boolean isByteOrderComparable() - { - return true; - } - - @Override - public boolean isCompatibleWith(AbstractType previous) - { - return super.isCompatibleWith(previous); - } - - @Override - public boolean isValueCompatibleWithInternal(AbstractType otherType) - { - return this == otherType || otherType == LongType.instance; - } - - public CQL3Type asCQL3Type() - { - return CQL3Type.Native.TIME; - } - - public TypeSerializer getSerializer() - { - return TimeSerializer.instance; - } -} diff --git a/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java b/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java deleted file mode 100644 index 221842bc2d..0000000000 --- a/src/java/org/apache/cassandra/serializers/SimpleDateSerializer.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.serializers; - -import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; - -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.LocalDate; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; - -import org.apache.cassandra.utils.ByteBufferUtil; - -// For byte-order comparability, we shift by Integer.MIN_VALUE and treat the data as an unsigned integer ranging from -// min date to max date w/epoch sitting in the center @ 2^31 -public class SimpleDateSerializer implements TypeSerializer -{ - private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd").withZone(DateTimeZone.UTC); - private static final long minSupportedDateMillis = TimeUnit.DAYS.toMillis(Integer.MIN_VALUE); - private static final long maxSupportedDateMillis = TimeUnit.DAYS.toMillis(Integer.MAX_VALUE); - private static final long maxSupportedDays = (long)Math.pow(2,32) - 1; - private static final long byteOrderShift = (long)Math.pow(2,31) * 2; - - private static final Pattern rawPattern = Pattern.compile("^-?\\d+$"); - public static final SimpleDateSerializer instance = new SimpleDateSerializer(); - - public Integer deserialize(ByteBuffer bytes) - { - return bytes.remaining() == 0 ? null : ByteBufferUtil.toInt(bytes); - } - - public ByteBuffer serialize(Integer value) - { - return value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value); - } - - public static Integer dateStringToDays(String source) throws MarshalException - { - // Raw day value in unsigned int form, epoch @ 2^31 - if (rawPattern.matcher(source).matches()) - { - try - { - Long result = Long.parseLong(source); - - if (result < 0 || result > maxSupportedDays) - throw new NumberFormatException("Input out of bounds: " + source); - - // Shift > epoch days into negative portion of Integer result for byte order comparability - if (result >= Integer.MAX_VALUE) - result -= byteOrderShift; - - return result.intValue(); - } - catch (NumberFormatException e) - { - throw new MarshalException(String.format("Unable to make unsigned int (for date) from: '%s'", source), e); - } - } - - // Attempt to parse as date string - try - { - DateTime parsed = formatter.parseDateTime(source); - long millis = parsed.getMillis(); - if (millis < minSupportedDateMillis) - throw new MarshalException(String.format("Input date %s is less than min supported date %s", source, new LocalDate(minSupportedDateMillis).toString())); - if (millis > maxSupportedDateMillis) - throw new MarshalException(String.format("Input date %s is greater than max supported date %s", source, new LocalDate(maxSupportedDateMillis).toString())); - - Integer result = (int)TimeUnit.MILLISECONDS.toDays(millis); - result -= Integer.MIN_VALUE; - return result; - } - catch (IllegalArgumentException e1) - { - throw new MarshalException(String.format("Unable to coerce '%s' to a formatted date (long)", source), e1); - } - } - - public void validate(ByteBuffer bytes) throws MarshalException - { - if (bytes.remaining() != 4) - throw new MarshalException(String.format("Expected 4 byte long for date (%d)", bytes.remaining())); - } - - public String toString(Integer value) - { - if (value == null) - return ""; - - return formatter.print(new LocalDate(TimeUnit.DAYS.toMillis(value - Integer.MIN_VALUE), DateTimeZone.UTC)); - } - - public Class getType() - { - return Integer.class; - } -} diff --git a/src/java/org/apache/cassandra/serializers/TimeSerializer.java b/src/java/org/apache/cassandra/serializers/TimeSerializer.java deleted file mode 100644 index b02d4259e2..0000000000 --- a/src/java/org/apache/cassandra/serializers/TimeSerializer.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.cassandra.serializers; - -import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; -import java.util.regex.Pattern; - -import org.apache.cassandra.utils.ByteBufferUtil; - -public class TimeSerializer implements TypeSerializer -{ - public static final Pattern timePattern = Pattern.compile("^-?\\d+$"); - public static final TimeSerializer instance = new TimeSerializer(); - - public Long deserialize(ByteBuffer bytes) - { - return bytes.remaining() == 0 ? null : ByteBufferUtil.toLong(bytes); - } - - public ByteBuffer serialize(Long value) - { - return value == null ? ByteBufferUtil.EMPTY_BYTE_BUFFER : ByteBufferUtil.bytes(value); - } - - public static Long timeStringToLong(String source) throws MarshalException - { - // nano since start of day, raw - if (timePattern.matcher(source).matches()) - { - try - { - Long result = Long.parseLong(source); - if (result < 0 || result > TimeUnit.DAYS.toNanos(1)) - throw new NumberFormatException("Input long out of bounds: " + source); - return result; - } - catch (NumberFormatException e) - { - throw new MarshalException(String.format("Unable to make long (for time) from: '%s'", source), e); - } - } - - // Last chance, attempt to parse as time string - try - { - return parseTimeStrictly(source); - } - catch (IllegalArgumentException e1) - { - throw new MarshalException(String.format("(TimeType) Unable to coerce '%s' to a formatted time (long)", source), e1); - } - } - - public void validate(ByteBuffer bytes) throws MarshalException - { - if (bytes.remaining() != 8) - throw new MarshalException(String.format("Expected 8 byte long for time (%d)", bytes.remaining())); - } - - public String toString(Long value) - { - if (value == null) - return "null"; - - int nano = (int)(value % 1000); - value -= nano; - value /= 1000; - int micro = (int)(value % 1000); - value -= micro; - value /= 1000; - int milli = (int)(value % 1000); - value -= milli; - value /= 1000; - int seconds = (int)(value % 60); - value -= seconds; - value /= 60; - int minutes = (int)(value % 60); - value -= minutes; - value /= 60; - int hours = (int)(value % 24); - value -= hours; - value /= 24; - assert(value == 0); - - StringBuilder sb = new StringBuilder(); - leftPadZeros(hours, 2, sb); - sb.append(":"); - leftPadZeros(minutes, 2, sb); - sb.append(":"); - leftPadZeros(seconds, 2, sb); - sb.append("."); - leftPadZeros(milli, 3, sb); - leftPadZeros(micro, 3, sb); - leftPadZeros(nano, 3, sb); - return sb.toString(); - } - - private void leftPadZeros(int value, int digits, StringBuilder sb) - { - for (int i = 1; i < digits; ++i) - { - if (value < Math.pow(10, i)) - sb.append("0"); - } - sb.append(value); - } - - public Class getType() - { - return Long.class; - } - - // Time specific parsing loosely based on java.sql.Timestamp - private static Long parseTimeStrictly(String s) throws IllegalArgumentException - { - String nanos_s; - - long hour; - long minute; - long second; - long a_nanos = 0; - - int firstColon = 0; - int secondColon = 0; - int period = 0; - String formatError = "Timestamp format must be hh:mm:ss[.fffffffff]"; - String zeros = "000000000"; - - if (s == null) - throw new java.lang.IllegalArgumentException(formatError); - s = s.trim(); - - // Parse the time - firstColon = s.indexOf(':'); - secondColon = s.indexOf(':', firstColon+1); - period = s.indexOf('.', secondColon+1); - - // Convert the time; default missing nanos - if (firstColon > 0 && secondColon > 0 && secondColon < s.length() - 1) - { - hour = Integer.parseInt(s.substring(0, firstColon)); - if (hour < 0 || hour >= 24) - throw new IllegalArgumentException("Hour out of bounds."); - - minute = Integer.parseInt(s.substring(firstColon + 1, secondColon)); - if (minute < 0 || minute >= 60) - throw new IllegalArgumentException("Minute out of bounds."); - - if (period > 0 && period < s.length() - 1) - { - second = Integer.parseInt(s.substring(secondColon + 1, period)); - if (second < 0 || second >= 60) - throw new IllegalArgumentException("Second out of bounds."); - - nanos_s = s.substring(period + 1); - if (nanos_s.length() > 9) - throw new IllegalArgumentException(formatError); - if (!Character.isDigit(nanos_s.charAt(0))) - throw new IllegalArgumentException(formatError); - nanos_s = nanos_s + zeros.substring(0, 9 - nanos_s.length()); - a_nanos = Integer.parseInt(nanos_s); - } - else if (period > 0) - throw new IllegalArgumentException(formatError); - else - { - second = Integer.parseInt(s.substring(secondColon + 1)); - if (second < 0 || second >= 60) - throw new IllegalArgumentException("Second out of bounds."); - } - } - else - throw new IllegalArgumentException(formatError); - - long rawTime = 0; - rawTime += TimeUnit.HOURS.toNanos(hour); - rawTime += TimeUnit.MINUTES.toNanos(minute); - rawTime += TimeUnit.SECONDS.toNanos(second); - rawTime += a_nanos; - return rawTime; - } -} diff --git a/src/java/org/apache/cassandra/serializers/TypeSerializer.java b/src/java/org/apache/cassandra/serializers/TypeSerializer.java index cddef08379..7b037c0c21 100644 --- a/src/java/org/apache/cassandra/serializers/TypeSerializer.java +++ b/src/java/org/apache/cassandra/serializers/TypeSerializer.java @@ -35,4 +35,3 @@ public interface TypeSerializer public Class getType(); } - diff --git a/src/java/org/apache/cassandra/transport/DataType.java b/src/java/org/apache/cassandra/transport/DataType.java index e13194d9c7..0ea353aa1a 100644 --- a/src/java/org/apache/cassandra/transport/DataType.java +++ b/src/java/org/apache/cassandra/transport/DataType.java @@ -49,8 +49,6 @@ public enum DataType implements OptionCodec.Codecable VARINT (14, IntegerType.instance), TIMEUUID (15, TimeUUIDType.instance), INET (16, InetAddressType.instance), - DATE (17, DateType.instance), - TIME (18, TimeType.instance), LIST (32, null), MAP (33, null), SET (34, null), diff --git a/test/unit/org/apache/cassandra/db/marshal/SimpleDateTypeTest.java b/test/unit/org/apache/cassandra/db/marshal/SimpleDateTypeTest.java deleted file mode 100644 index 5c9ed4e225..0000000000 --- a/test/unit/org/apache/cassandra/db/marshal/SimpleDateTypeTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.cassandra.db.marshal; - -import java.nio.ByteBuffer; - -import org.junit.Test; -import org.apache.cassandra.serializers.SimpleDateSerializer; - -public class SimpleDateTypeTest -{ - @Test public void TestComparison() - { - ByteBuffer d1 = SimpleDateType.instance.fromString("1970-01-05"); - ByteBuffer d2 = SimpleDateSerializer.instance.serialize(makeUnsigned(4)); - assert SimpleDateType.instance.compare(d1, d2) == 0 : "Failed == comparison"; - String.format("Failed == comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("1970-01-05"); - d2 = SimpleDateSerializer.instance.serialize(makeUnsigned(10)); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed comparison of %s and %s, expected <", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("1970-01-05"); // 4 - d2 = SimpleDateSerializer.instance.serialize(makeUnsigned(-10)); - assert SimpleDateType.instance.compare(d1, d2) > 0 : - String.format("Failed comparison of %s and %s, expected > 0", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("1"); - d2 = SimpleDateType.instance.fromString("1000"); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed < comparison with string inputs %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - Integer intLimit = Integer.MAX_VALUE; - d1 = SimpleDateType.instance.fromString("0"); - d2 = SimpleDateType.instance.fromString(intLimit.toString()); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed < comparison with string inputs at integer bounds %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - Long overLimit = (long)(Integer.MAX_VALUE); - d1 = SimpleDateType.instance.fromString("0"); - d2 = SimpleDateType.instance.fromString(overLimit.toString()); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed < comparison with string inputs at integer bounds %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - Long i1 = 0L; - Long i2 = (long)Math.pow(2,32) - 1; - d1 = SimpleDateType.instance.fromString(i1.toString()); - d2 = SimpleDateType.instance.fromString(i2.toString()); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed limits comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("256"); - d2 = SimpleDateType.instance.fromString("512"); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateSerializer.instance.serialize(makeUnsigned(0)); - d2 = SimpleDateSerializer.instance.serialize(makeUnsigned(Integer.MAX_VALUE)); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed neg/pos comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("-10000-10-10"); - d2 = SimpleDateType.instance.fromString("10000-10-10"); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed neg/pos string comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("1969-12-31"); - d2 = SimpleDateType.instance.fromString("1970-1-1"); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed pre/post epoch comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("1970-1-1"); - d2 = SimpleDateType.instance.fromString("1970-1-1"); - assert SimpleDateType.instance.compare(d1, d2) == 0 : - String.format("Failed == date from string comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - d1 = SimpleDateType.instance.fromString("1970-1-1"); - d2 = SimpleDateType.instance.fromString("1970-1-2"); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed post epoch string comparison with %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - - for (int i = 0; i < 32; ++i) - { - int offset = (int)Math.pow(2,i); - d1 = SimpleDateSerializer.instance.serialize(makeUnsigned(0 - offset)); - d2 = SimpleDateSerializer.instance.serialize(makeUnsigned(offset)); - assert SimpleDateType.instance.compare(d1, d2) < 0 : - String.format("Failed < comparison of %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - } - - for (int i = 0; i < 32; ++i) - { - int offset = (int)Math.pow(2,i); - d1 = SimpleDateSerializer.instance.serialize(makeUnsigned(offset)); - d2 = SimpleDateSerializer.instance.serialize(makeUnsigned(0 - offset)); - assert SimpleDateType.instance.compare(d1, d2) > 0 : - String.format("Failed > comparison of %s and %s", - SimpleDateSerializer.instance.deserialize(d1), - SimpleDateSerializer.instance.deserialize(d2)); - } - } - - private Integer makeUnsigned(int input) - { - return input - Integer.MIN_VALUE; - } -} diff --git a/test/unit/org/apache/cassandra/db/marshal/TimeTypeTest.java b/test/unit/org/apache/cassandra/db/marshal/TimeTypeTest.java deleted file mode 100644 index 3057b9c4d7..0000000000 --- a/test/unit/org/apache/cassandra/db/marshal/TimeTypeTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.cassandra.db.marshal; - -import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; - -import org.junit.Test; -import org.apache.cassandra.serializers.TimeSerializer; - -public class TimeTypeTest -{ - @Test public void TestComparison() - { - Long t1 = TimeSerializer.timeStringToLong("01:00:00.123456789"); - Long t2 = new Long((1L * 60L * 60L * 1000L * 1000L * 1000L) + 123456789); - ByteBuffer b1 = TimeSerializer.instance.serialize(t1); - ByteBuffer b2 = TimeSerializer.instance.serialize(t2); - assert TimeType.instance.compare(b1, b2) == 0 : "Failed == comparison"; - - b2 = TimeSerializer.instance.serialize(123456789L); - assert TimeType.instance.compare(b1, b2) > 0 : "Failed > comparison"; - - t2 = new Long(2L * 60L * 60L * 1000L * 1000L * 1000L + 123456789); - b2 = TimeSerializer.instance.serialize(t2); - assert TimeType.instance.compare(b1, b2) < 0 : "Failed < comparison"; - - b1 = TimeSerializer.instance.serialize(0L); - b2 = TimeSerializer.instance.serialize(0L); - assert TimeType.instance.compare(b1, b2) == 0 : "Failed == comparison on 0"; - - b1 = TimeSerializer.instance.serialize(0L); - b2 = TimeSerializer.instance.serialize(10000000L); - assert TimeType.instance.compare(b1, b2) == -1 : "Failed < comparison on 0"; - - b1 = TimeSerializer.instance.serialize(0L); - b2 = TimeSerializer.instance.serialize(TimeUnit.DAYS.toNanos(1)); - assert TimeType.instance.compare(b1, b2) == -1 : "Failed < comparison against max range."; - - b1 = TimeSerializer.instance.serialize(TimeUnit.DAYS.toNanos(1)); - b2 = TimeSerializer.instance.serialize(0L); - assert TimeType.instance.compare(b1, b2) == 1 : "Failed > comparison against max range."; - } -} diff --git a/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java b/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java deleted file mode 100644 index 4c0751f06d..0000000000 --- a/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cassandra.serializers; - -import org.apache.cassandra.db.marshal.SimpleDateType; -import org.apache.cassandra.utils.Pair; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.*; - -public class SimpleDateSerializerTest -{ - private static final long millisPerDay = 1000 * 60 * 60 * 24; - - private String dates[] = new String[] - { - "1970-01-01", - "1970-01-02", - "1969-12-31", - "-0001-01-02", - "-5877521-01-02", - "2014-01-01", - "5881580-01-10", - "1920-12-01", - "1582-10-19" - }; - - private static GregorianCalendar testCalendar = new GregorianCalendar(); - private static SimpleDateFormat dateFormatUTC = new SimpleDateFormat("yyyy-MM-dd"); - - { - testCalendar.setGregorianChange(new Date(Long.MIN_VALUE)); - testCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); - dateFormatUTC.setCalendar(testCalendar); - dateFormatUTC.setLenient(false); - } - - @Test - public void testDateStringToTimestamp() - { - List unparsedDates = new ArrayList<>(); - List badParseResults = new ArrayList<>(); - for (String date : dates) - { - try - { - Integer days = SimpleDateSerializer.dateStringToDays(date); - ByteBuffer value = SimpleDateSerializer.instance.serialize(days); - Integer deserialized = SimpleDateSerializer.instance.deserialize(value); - - String toStringValue = SimpleDateSerializer.instance.toString(deserialized); - if (!date.equals(toStringValue)) { - badParseResults.add(String.format("Failed to parse date correctly. Expected %s, got %s\n", date, toStringValue)); - } - } - catch (MarshalException e) - { - System.err.println("Got an exception: " + e); - unparsedDates.add(date); - } - } - assert unparsedDates.isEmpty() : "Unable to parse: " + unparsedDates; - assert badParseResults.isEmpty() : "Incorrect parse results: " + badParseResults; - } - - @Test - public void testDaysStringToInt() - { - Integer value = SimpleDateSerializer.dateStringToDays("12345"); - assert value.compareTo(12345) == 0 : String.format("Failed to parse integer based date. Expected %s, got %s", - 12345, - value); - } - - @Test - public void testProlepticRange() - { - for (int i = 1; i < 31; ++i) - { - String date = "1582-10-"; - if (i < 10) date += "0"; - date += i; - - Integer days = SimpleDateSerializer.dateStringToDays(date); - - ByteBuffer value = SimpleDateType.instance.fromString(days.toString()); - Integer deserialized = SimpleDateSerializer.instance.deserialize(value); - - // Serialized values are unsigned int, unwrap bits w/overflow - deserialized -= Integer.MIN_VALUE; - - Timestamp ts = new Timestamp(deserialized * millisPerDay); - testCalendar.setTime(ts); - - Date newDate = testCalendar.getTime(); - assert (dateFormatUTC.format(newDate)).equals(date) : - String.format("Expected [%s], got [%s]", date, dateFormatUTC.format(newDate).toString()); - } - } - - @Test (expected=MarshalException.class) - public void testOutOfBoundsLow() - { - Integer days = SimpleDateSerializer.dateStringToDays(new Date(Integer.MIN_VALUE * millisPerDay - millisPerDay).toString()); - } - - @Test (expected=MarshalException.class) - public void testOutOfBoundsHigh() - { - Integer days = SimpleDateSerializer.dateStringToDays(new Date(Integer.MAX_VALUE * millisPerDay + millisPerDay).toString()); - } - - @Test (expected=MarshalException.class) - public void testBadInput() - { - Integer days = SimpleDateSerializer.dateStringToDays("12A-01-01"); - } - - @Test (expected=MarshalException.class) - public void testBadMonth() - { - Integer days = SimpleDateSerializer.dateStringToDays("1000-13-01"); - } - - @Test (expected=MarshalException.class) - public void testBadDay() - { - Integer days = SimpleDateSerializer.dateStringToDays("1000-12-32"); - } - - @Test (expected=MarshalException.class) - public void testBadDayToMonth() - { - Integer days = SimpleDateSerializer.dateStringToDays("1000-09-31"); - } -} diff --git a/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java b/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java deleted file mode 100644 index f8af48c7f1..0000000000 --- a/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java +++ /dev/null @@ -1,242 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.cassandra.serializers; - -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.util.concurrent.TimeUnit; - -public class TimeSerializerTest -{ - @Test - public void testSerializerFromString() - { - // nano - long expected = 5; - Long time = TimeSerializer.timeStringToLong("00:00:00.000000005"); - assert time == expected : String.format("Failed nano conversion. Expected %s, got %s", expected, time); - - // usec - expected = TimeUnit.MICROSECONDS.toNanos(123); - time = TimeSerializer.timeStringToLong("00:00:00.000123000"); - assert time == expected : String.format("Failed usec conversion. Expected %s, got %s", expected, time); - - // milli - expected = TimeUnit.MILLISECONDS.toNanos(123); - time = TimeSerializer.timeStringToLong("00:00:00.123000"); - assert time == expected : String.format("Failed milli conversion. Expected %s, got %s", expected, time); - - // sec - expected = TimeUnit.SECONDS.toNanos(15); - time = TimeSerializer.timeStringToLong("00:00:15.000"); - assert time == expected : String.format("Failed sec conversion. Expected %s, got %s", expected, time); - - // min - expected = TimeUnit.MINUTES.toNanos(13); - time = TimeSerializer.timeStringToLong("00:13:00.000"); - assert time == expected : String.format("Failed min conversion. Expected %s, got %s", expected, time); - - // hour - expected = TimeUnit.HOURS.toNanos(2); - time = TimeSerializer.timeStringToLong("02:0:00.000"); - assert time == expected : String.format("Failed min conversion. Expected %s, got %s", expected, time); - - // complex - expected = buildExpected(4, 31, 12, 123, 456, 789); - time = TimeSerializer.timeStringToLong("4:31:12.123456789"); - assert time == expected : String.format("Failed complex conversion. Expected %s, got %s", expected, time); - - // upper bound - expected = buildExpected(23, 59, 59, 999, 999, 999); - time = TimeSerializer.timeStringToLong("23:59:59.999999999"); - assert time == expected : String.format("Failed upper bounds conversion. Expected %s, got %s", expected, time); - - // Test partial nano - expected = buildExpected(12, 13, 14, 123, 654, 120); - time = TimeSerializer.timeStringToLong("12:13:14.12365412"); - assert time == expected : String.format("Failed partial nano timestring. Expected %s, got %s", expected, time); - - // Test raw long value - expected = 10; - time = TimeSerializer.timeStringToLong("10"); - assert time == expected : String.format("Failed long conversion. Expected %s, got %s", expected, time); - - // Test 0 long - expected = 0; - time = TimeSerializer.timeStringToLong("0"); - assert time == expected : String.format("Failed long conversion. Expected %s, got %s", expected, time); - } - - private long buildExpected(int hour, int minute, int second, int milli, int micro, int nano) - { - return TimeUnit.HOURS.toNanos(hour) + - TimeUnit.MINUTES.toNanos(minute) + - TimeUnit.SECONDS.toNanos(second) + - TimeUnit.MILLISECONDS.toNanos(milli) + - TimeUnit.MICROSECONDS.toNanos(micro) + - nano; - } - - @Test - public void testSerializerToString() - { - String source = "00:00:00.000000011"; - Long time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - source = "00:00:00.000012311"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - source = "00:00:00.123000000"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - source = "00:00:12.123450000"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - source = "00:34:12.123450000"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - source = "15:00:12.123450000"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - // boundaries - source = "00:00:00.000000000"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - source = "23:59:59.999999999"; - time = TimeSerializer.timeStringToLong(source); - assert(source.equals(TimeSerializer.instance.toString(time))); - - // truncated - source = "01:14:18.12"; - time = TimeSerializer.timeStringToLong(source); - String result = TimeSerializer.instance.toString(time); - assert(result.equals("01:14:18.120000000")); - - source = "01:14:18.1201"; - time = TimeSerializer.timeStringToLong(source); - result = TimeSerializer.instance.toString(time); - assert(result.equals("01:14:18.120100000")); - - source = "01:14:18.1201098"; - time = TimeSerializer.timeStringToLong(source); - result = TimeSerializer.instance.toString(time); - assert(result.equals("01:14:18.120109800")); - } - - @Test public void testSerialization() - { - String source = "01:01:01.123123123"; - Long nt = TimeSerializer.timeStringToLong(source); - - ByteBuffer buf = TimeSerializer.instance.serialize(nt); - TimeSerializer.instance.validate(buf); - - Long result = TimeSerializer.instance.deserialize(buf); - String strResult = TimeSerializer.instance.toString(result); - - assert(strResult.equals(source)); - } - - @Test (expected=MarshalException.class) - public void testBadHourLow() - { - Long time = TimeSerializer.timeStringToLong("-1:0:0.123456789"); - } - - @Test (expected=MarshalException.class) - public void testBadHourHigh() - { - Long time = TimeSerializer.timeStringToLong("24:0:0.123456789"); - } - - @Test (expected=MarshalException.class) - public void testBadMinuteLow() - { - Long time = TimeSerializer.timeStringToLong("23:-1:0.123456789"); - } - - @Test (expected=MarshalException.class) - public void testBadMinuteHigh() - { - Long time = TimeSerializer.timeStringToLong("23:60:0.123456789"); - } - - @Test (expected=MarshalException.class) - public void testEmpty() - { - Long time = TimeSerializer.timeStringToLong(""); - } - - @Test (expected=MarshalException.class) - public void testBadSecondLow() - { - Long time = TimeSerializer.timeStringToLong("23:59:-1.123456789"); - } - - @Test (expected=MarshalException.class) - public void testBadSecondHigh() - { - Long time = TimeSerializer.timeStringToLong("23:59:60.123456789"); - } - - @Test (expected=MarshalException.class) - public void testBadSecondHighNoMilli() - { - Long time = TimeSerializer.timeStringToLong("23:59:60"); - } - - @Test (expected=MarshalException.class) - public void testBadNanoLow() - { - Long time = TimeSerializer.timeStringToLong("23:59:59.-123456789"); - } - - @Test (expected=MarshalException.class) - public void testBadNanoHigh() - { - Long time = TimeSerializer.timeStringToLong("23:59:59.1234567899"); - } - - @Test (expected=MarshalException.class) - public void testBadNanoCharacter() - { - Long time = TimeSerializer.timeStringToLong("23:59:59.12345A789"); - } - - @Test (expected=MarshalException.class) - public void testNegativeLongTime() - { - Long time = TimeSerializer.timeStringToLong("-10"); - } - - @Test (expected=MarshalException.class) - public void testRawLongOverflow() - { - Long input = TimeUnit.DAYS.toNanos(1) + 1; - Long time = TimeSerializer.timeStringToLong(input.toString()); - } -}