cqlsh: Don't show 'null' in place of empty values patch by Aleksey Yeschenko; reviewed by Brandon Williams for CASSANDRA-5675
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/e4050e60 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/e4050e60 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/e4050e60 Branch: refs/heads/trunk Commit: e4050e609cc4bdc4b60ffb829774a7ce09dad726 Parents: 33a3d2c Author: Aleksey Yeschenko <alek...@apache.org> Authored: Thu Jun 27 00:36:46 2013 +0300 Committer: Aleksey Yeschenko <alek...@apache.org> Committed: Thu Jun 27 01:03:07 2013 +0300 ---------------------------------------------------------------------- CHANGES.txt | 1 + bin/cqlsh | 30 ++++++++++++++++++------ pylib/cqlshlib/displaying.py | 4 ++-- pylib/cqlshlib/formatting.py | 6 +++-- pylib/cqlshlib/test/test_cqlsh_output.py | 10 ++++---- pylib/cqlshlib/test/test_keyspace_init2.cql | 4 ++++ 6 files changed, 39 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4050e60/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index 24d4c9e..e7e8652 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,7 @@ 1.2.7 * Fix serialization of the LEFT gossip value (CASSANDRA-5696) * Pig: support for cql3 tables (CASSANDRA-5234) + * cqlsh: Don't show 'null' in place of empty values (CASSANDRA-5675) 1.2.6 * Fix tracing when operation completes before all responses arrive (CASSANDRA-5668) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4050e60/bin/cqlsh ---------------------------------------------------------------------- diff --git a/bin/cqlsh b/bin/cqlsh index 70b70f5..9f1e6cf 100755 --- a/bin/cqlsh +++ b/bin/cqlsh @@ -567,6 +567,17 @@ class Shell(cmd.Cmd): def myformat_colname(self, name, nametype): return self.myformat_value(name, nametype, colormap=COLUMN_NAME_COLORS) + # cql/cursor.py:Cursor.decode_row() function, modified to not turn '' into None. + def decode_row(self, cursor, row): + values = [] + bytevals = cursor.columnvalues(row) + for val, vtype, nameinfo in zip(bytevals, cursor.column_types, cursor.name_info): + if val == '': + values.append(val) + else: + values.append(cursor.decoder.decode_value(val, vtype, nameinfo[0])) + return values + def report_connection(self): self.show_host() self.show_version() @@ -1115,7 +1126,7 @@ class Shell(cmd.Cmd): colnames = [d[0] for d in cursor.description] colnames_t = [(name, self.get_nametype(cursor, n)) for (n, name) in enumerate(colnames)] formatted_names = [self.myformat_colname(name, nametype) for (name, nametype) in colnames_t] - formatted_values = [map(self.myformat_value, row, cursor.column_types) for row in cursor] + formatted_values = [map(self.myformat_value, self.decode_row(cursor, row), cursor.column_types) for row in cursor.result] if self.expand_enabled: self.print_formatted_result_vertically(formatted_names, formatted_values) else: @@ -1153,11 +1164,12 @@ class Shell(cmd.Cmd): self.writeresult('') def print_dynamic_result(self, cursor): - for row in cursor: + for row in cursor.result: + cursor.fetchone() colnames = [d[0] for d in cursor.description] colnames_t = [(name, self.get_nametype(cursor, n)) for (n, name) in enumerate(colnames)] colnames = [self.myformat_colname(name, nametype) for (name, nametype) in colnames_t] - colvals = map(self.myformat_value, row, cursor.column_types) + colvals = map(self.myformat_value, self.decode_row(cursor, row), cursor.column_types) line = ' | '.join('%s,%s' % (n.coloredval, v.coloredval) for (n, v) in zip(colnames, colvals)) self.writeresult(' ' + line) @@ -1680,14 +1692,18 @@ class Shell(cmd.Cmd): def do_import_row(self, columns, nullval, layout, row): rowmap = {} for name, value in zip(columns, row): + type = layout.get_column(name).cqltype + if issubclass(type, ReversedType): + type = type.subtypes[0] + cqltype = type.cql_parameterized_type() + if value != nullval: - type = layout.get_column(name).cqltype - if issubclass(type, ReversedType): - type = type.subtypes[0] - if type.cql_parameterized_type() in ('ascii', 'text', 'timestamp', 'inet'): + if cqltype in ('ascii', 'text', 'timestamp', 'inet'): rowmap[name] = self.cql_protect_value(value) else: rowmap[name] = value + elif name in layout.column_aliases and not type.empty_binary_ok: + rowmap[name] = 'blobAs%s(0x)' % cqltype.title() else: rowmap[name] = 'null' return self.do_import_insert(layout, rowmap) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4050e60/pylib/cqlshlib/displaying.py ---------------------------------------------------------------------- diff --git a/pylib/cqlshlib/displaying.py b/pylib/cqlshlib/displaying.py index 22ff763..13e3cf4 100644 --- a/pylib/cqlshlib/displaying.py +++ b/pylib/cqlshlib/displaying.py @@ -93,7 +93,7 @@ DEFAULT_VALUE_COLORS = dict( default=YELLOW, text=YELLOW, error=RED, - hex=DARK_MAGENTA, + blob=DARK_MAGENTA, timestamp=GREEN, int=GREEN, float=GREEN, @@ -107,6 +107,6 @@ DEFAULT_VALUE_COLORS = dict( COLUMN_NAME_COLORS = defaultdict(lambda: MAGENTA, error=RED, - hex=DARK_MAGENTA, + blob=DARK_MAGENTA, reset=ANSI_RESET, ) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4050e60/pylib/cqlshlib/formatting.py ---------------------------------------------------------------------- diff --git a/pylib/cqlshlib/formatting.py b/pylib/cqlshlib/formatting.py index a3d4666..87f692b 100644 --- a/pylib/cqlshlib/formatting.py +++ b/pylib/cqlshlib/formatting.py @@ -79,7 +79,7 @@ def color_text(bval, colormap, displaywidth=None): if displaywidth is None: displaywidth = len(bval) - tbr = _make_turn_bits_red_f(colormap['hex'], colormap['text']) + tbr = _make_turn_bits_red_f(colormap['blob'], colormap['text']) coloredval = colormap['text'] + bits_to_turn_red_re.sub(tbr, bval) + colormap['reset'] if colormap['text']: displaywidth -= bval.count(r'\\') @@ -96,6 +96,8 @@ def format_value_default(val, colormap, **_): _formatters = {} def format_value(cqltype, val, **kwargs): + if val == '' and not cqltype.empty_binary_ok: + return format_value_default(val, **kwargs) formatter = _formatters.get(cqltype.typename, format_value_default) return formatter(val, subtypes=cqltype.subtypes, **kwargs) @@ -108,7 +110,7 @@ def formatter_for(typname): @formatter_for('blob') def format_value_blob(val, colormap, **_): bval = '0x' + ''.join('%02x' % ord(c) for c in val) - return colorme(bval, colormap, 'hex') + return colorme(bval, colormap, 'blob') def format_python_formatted_type(val, colormap, color): bval = str(val) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4050e60/pylib/cqlshlib/test/test_cqlsh_output.py ---------------------------------------------------------------------- diff --git a/pylib/cqlshlib/test/test_cqlsh_output.py b/pylib/cqlshlib/test/test_cqlsh_output.py index 6ca251e..07abc29 100644 --- a/pylib/cqlshlib/test/test_cqlsh_output.py +++ b/pylib/cqlshlib/test/test_cqlsh_output.py @@ -153,7 +153,7 @@ class TestCqlshOutput(BaseTestCase): MMMMM ------- - 4 + 5 G """), @@ -371,7 +371,7 @@ class TestCqlshOutput(BaseTestCase): self.assertCqlverQueriesGiveColoredOutput(( ('''select intcol, bigintcol, varintcol \ from has_all_types \ - where num in (0, 1, 2, 3);''', """ + where num in (0, 1, 2, 3, 4);''', """ intcol | bigintcol | varintcol MMMMMM MMMMMMMMM MMMMMMMMM -------------+----------------------+----------------------------- @@ -384,12 +384,12 @@ class TestCqlshOutput(BaseTestCase): GGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGG -2147483648 | -9223372036854775808 | -10000000000000000000000000 GGGGGGGGGGG GGGGGGGGGGGGGGGGGGGG GGGGGGGGGGGGGGGGGGGGGGGGGGG - + | | """), ('''select decimalcol, doublecol, floatcol \ from has_all_types \ - where num in (0, 1, 2, 3);''', """ + where num in (0, 1, 2, 3, 4);''', """ decimalcol | doublecol | floatcol MMMMMMMMMM MMMMMMMMM MMMMMMMM ------------------+-----------+---------- @@ -402,7 +402,7 @@ class TestCqlshOutput(BaseTestCase): GGGGGGGGGGGGGGGG GGGGGGG GGGGG 10.0000000000000 | -1004.1 | 1e+08 GGGGGGGGGGGGGGGG GGGGGGG GGGGG - + | | """), ), cqlver=(2, 3)) http://git-wip-us.apache.org/repos/asf/cassandra/blob/e4050e60/pylib/cqlshlib/test/test_keyspace_init2.cql ---------------------------------------------------------------------- diff --git a/pylib/cqlshlib/test/test_keyspace_init2.cql b/pylib/cqlshlib/test/test_keyspace_init2.cql index ca5f4a4..7194e8a 100644 --- a/pylib/cqlshlib/test/test_keyspace_init2.cql +++ b/pylib/cqlshlib/test/test_keyspace_init2.cql @@ -44,6 +44,10 @@ VALUES (3, -2147483648, '''''''', -9223372036854775808, '80', 'false', 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, '', '', '', '', '', '', '', '', '', '', '', '', ''); CREATE TABLE has_value_encoding_errors (