You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2012/05/01 16:52:37 UTC
[2/4] git commit: cqlsh: in cql3 mode,
use cql3 quoting when outputting cql. Patch by paul cannon,
reviewed by brandonwilliams for CASSANDRA-4173
cqlsh: in cql3 mode, use cql3 quoting when outputting cql.
Patch by paul cannon, reviewed by brandonwilliams for CASSANDRA-4173
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f1ee34f0
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f1ee34f0
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f1ee34f0
Branch: refs/heads/cassandra-1.1
Commit: f1ee34f08fdde93f4a79227a5d6d3987fe007d77
Parents: c5ad288
Author: Brandon Williams <br...@apache.org>
Authored: Tue May 1 09:48:27 2012 -0500
Committer: Brandon Williams <br...@apache.org>
Committed: Tue May 1 09:48:27 2012 -0500
----------------------------------------------------------------------
bin/cqlsh | 120 +++++++++++++++++++---------------
pylib/cqlshlib/cql3handling.py | 13 ++++-
2 files changed, 79 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/f1ee34f0/bin/cqlsh
----------------------------------------------------------------------
diff --git a/bin/cqlsh b/bin/cqlsh
index 00c6c0d..b1833fd 100755
--- a/bin/cqlsh
+++ b/bin/cqlsh
@@ -59,10 +59,7 @@ if os.path.isdir(cqlshlibdir):
sys.path.insert(0, cqlshlibdir)
from cqlshlib import cqlhandling, cql3handling, pylexotron, wcwidth
-from cqlshlib.cqlhandling import (token_dequote, cql_dequote, cql_escape,
- maybe_cql_escape, cql_typename)
-from cqlshlib.cql3handling import (CqlTableDef, maybe_cql3_escape_name,
- cql3_escape_value)
+from cqlshlib.cqlhandling import cql_typename
try:
import readline
@@ -235,32 +232,32 @@ def complete_help(ctxt, cqlsh):
@cqlhandling.cql_add_completer('describeCommand', 'ksname')
def complete_describe_ks(ctxt, cqlsh):
- return map(maybe_cql_escape, cqlsh.get_keyspace_names())
+ return map(cqlsh.cql_protect_name, cqlsh.get_keyspace_names())
@cqlhandling.cql_add_completer('describeCommand', 'cfname')
def complete_describe_cf(ctxt, cqlsh):
- return map(maybe_cql_escape, cqlsh.get_columnfamily_names())
+ return map(cqlsh.cql_protect_name, cqlsh.get_columnfamily_names())
@cqlhandling.cql_add_completer('assumeCommand', 'ks')
def complete_assume_ks(ctxt, cqlsh):
- return [maybe_cql_escape(ks) + '.' for ks in cqlsh.get_keyspace_names()]
+ return [cqlsh.cql_protect_name(ks) + '.' for ks in cqlsh.get_keyspace_names()]
@cqlhandling.cql_add_completer('assumeCommand', 'cf')
def complete_assume_cf(ctxt, cqlsh):
ks = ctxt.get_binding('ks', None)
if ks is not None:
- ks = cql_dequote(ks)
- return map(maybe_cql_escape, cqlsh.get_columnfamily_names(ks))
+ ks = cqlsh.cql_unprotect_name(ks)
+ return map(cqlsh.cql_protect_name, cqlsh.get_columnfamily_names(ks))
@cqlhandling.cql_add_completer('assumeTypeDef', 'colname')
def complete_assume_col(ctxt, cqlsh):
ks = ctxt.get_binding('ks', None)
- ks = cql_dequote(ks) if ks is not None else None
- cf = cql_dequote(ctxt.get_binding('cf'))
+ ks = cqlsh.cql_unprotect_name(ks) if ks is not None else None
+ cf = cqlsh.cql_unprotect_name(ctxt.get_binding('cf'))
cfdef = cqlsh.get_columnfamily(cf, ksname=ks)
cols = [cm.name for cm in cfdef.column_metadata]
cols.append(cfdef.key_alias or 'KEY')
- return map(maybe_cql_escape, cols)
+ return map(cqlsh.cql_protect_name, cols)
def complete_source_quoted_filename(ctxt, cqlsh):
partial = ctxt.get_binding('partial', '')
@@ -576,11 +573,11 @@ class Shell(cmd.Cmd):
print 'No overrides.'
return
for keyspace, ksoverrides in groupby(all_overrides, key=lambda x:x[0][0]):
- keyspace = maybe_cql_escape(keyspace)
+ keyspace = self.cql_protect_name(keyspace)
print 'USE %s;' % keyspace
print
for (ks, cf), override in ksoverrides:
- cf = maybe_cql_escape(cf)
+ cf = self.cql_protect_name(cf)
if override.default_name_type:
print 'ASSUME %s NAMES ARE %s;' \
% (cf, cql_typename(override.default_name_type))
@@ -588,7 +585,7 @@ class Shell(cmd.Cmd):
print 'ASSUME %s VALUES ARE %s;' \
% (cf, cql_typename(override.default_value_type))
for colname, vtype in override.value_types.items():
- colname = maybe_cql_escape(colname)
+ colname = self.cql_protect_name(colname)
print 'ASSUME %s(%s) VALUES ARE %s;' \
% (cf, colname, cql_typename(vtype))
print
@@ -715,7 +712,7 @@ class Shell(cmd.Cmd):
where "keyspace"=:ks and "columnfamily"=:cf""",
{'ks': ksname, 'cf': cfname})
cols = self.fetchdict_all()
- return CqlTableDef.from_layout(layout, cols)
+ return cql3handling.CqlTableDef.from_layout(layout, cols)
# ===== end cql3-dependent parts =====
@@ -873,7 +870,7 @@ class Shell(cmd.Cmd):
"""
ksname = parsed.get_binding('ksname')
if self.perform_statement(parsed.extract_orig()):
- self.current_keyspace = cql_dequote(ksname)
+ self.current_keyspace = self.cql_unprotect_name(ksname)
def do_select(self, parsed):
"""
@@ -897,8 +894,8 @@ class Shell(cmd.Cmd):
"""
ksname = parsed.get_binding('selectks')
if ksname is not None:
- ksname = cql_dequote(ksname)
- cfname = cql_dequote(parsed.get_binding('selectsource'))
+ ksname = self.cql_unprotect_name(ksname)
+ cfname = self.cql_unprotect_name(parsed.get_binding('selectsource'))
decoder = self.determine_decoder_for(cfname, ksname=ksname)
self.perform_statement(parsed.extract_orig(), decoder=decoder)
@@ -1062,13 +1059,30 @@ class Shell(cmd.Cmd):
if self.prompt != '':
self.prompt = prompt
+ def cql_protect_name(self, name):
+ if self.cqlver_atleast(3):
+ return cql3handling.maybe_cql3_escape_name(name)
+ else:
+ return cqlhandling.maybe_cql_escape(name)
+
+ def cql_protect_value(self, value):
+ return cqlhandling.cql_escape(value)
+
+ def cql_unprotect_name(self, namestr):
+ if namestr is not None:
+ return cql3handling.cql3_dequote_name(namestr)
+
+ def cql_unprotect_value(self, valstr):
+ if valstr is not None:
+ return cqlhandling.cql_dequote(valstr)
+
def print_recreate_keyspace(self, ksdef, out):
stratclass = trim_if_present(ksdef.strategy_class, 'org.apache.cassandra.locator.')
- ksname = maybe_cql_escape(ksdef.name)
+ ksname = self.cql_protect_name(ksdef.name)
out.write("CREATE KEYSPACE %s WITH strategy_class = %s"
- % (ksname, cql_escape(stratclass)))
+ % (ksname, self.cql_protect_value(stratclass)))
for opname, opval in ksdef.strategy_options.iteritems():
- out.write("\n AND strategy_options:%s = %s" % (opname, cql_escape(opval)))
+ out.write("\n AND strategy_options:%s = %s" % (opname, self.cql_protect_value(opval)))
out.write(';\n')
if ksdef.cf_defs:
@@ -1111,41 +1125,41 @@ class Shell(cmd.Cmd):
return self.print_recreate_columnfamily_from_cfdef(cfdef, out)
def print_recreate_columnfamily_from_cfdef(self, cfdef, out):
- cfname = maybe_cql_escape(cfdef.name)
+ cfname = self.cql_protect_name(cfdef.name)
out.write("CREATE COLUMNFAMILY %s (\n" % cfname)
- alias = maybe_cql_escape(cfdef.key_alias) if cfdef.key_alias else 'KEY'
+ alias = self.cql_protect_name(cfdef.key_alias) if cfdef.key_alias else 'KEY'
keytype = cql_typename(cfdef.key_validation_class)
out.write(" %s %s PRIMARY KEY" % (alias, keytype))
indexed_columns = []
for col in cfdef.column_metadata:
- colname = maybe_cql_escape(col.name)
+ colname = self.cql_protect_name(col.name)
out.write(",\n %s %s" % (colname, cql_typename(col.validation_class)))
if col.index_name is not None:
indexed_columns.append(col)
- notable_columns = []
+ cf_opts = []
for (option, thriftname) in cqlhandling.columnfamily_options:
optval = getattr(cfdef, thriftname or option, None)
if optval is None:
continue
if option in ('comparator', 'default_validation'):
optval = cql_typename(optval)
- elif option == 'row_cache_provider':
- optval = cql_escape(trim_if_present(optval, 'org.apache.cassandra.cache.'))
- elif option == 'compaction_strategy_class':
- optval = cql_escape(trim_if_present(optval, 'org.apache.cassandra.db.compaction.'))
else:
- optval = cql_escape(optval)
- notable_columns.append((option, optval))
+ if option == 'row_cache_provider':
+ optval = trim_if_present(optval, 'org.apache.cassandra.cache.')
+ elif option == 'compaction_strategy_class':
+ optval = trim_if_present(optval, 'org.apache.cassandra.db.compaction.')
+ optval = self.cql_protect_value(optval)
+ cf_opts.append((option, optval))
for option, thriftname, _ in cqlhandling.columnfamily_map_options:
optmap = getattr(cfdef, thriftname or option, {})
for k, v in optmap.items():
if option == 'compression_parameters' and k == 'sstable_compression':
v = trim_if_present(v, 'org.apache.cassandra.io.compress.')
- notable_columns.append(('%s:%s' % (option, k), cql_escape(v)))
+ cf_opts.append(('%s:%s' % (option, k), self.cql_protect_value(v)))
out.write('\n)')
- if notable_columns:
+ if cf_opts:
joiner = 'WITH'
- for optname, optval in notable_columns:
+ for optname, optval in cf_opts:
out.write(" %s\n %s=%s" % (joiner, optname, optval))
joiner = 'AND'
out.write(";\n")
@@ -1154,25 +1168,25 @@ class Shell(cmd.Cmd):
out.write('\n')
# guess CQL can't represent index_type or index_options
out.write('CREATE INDEX %s ON %s (%s);\n'
- % (col.index_name, cfname, maybe_cql_escape(col.name)))
+ % (col.index_name, cfname, self.cql_protect_name(col.name)))
def print_recreate_columnfamily_from_layout(self, layout, out):
- cfname = maybe_cql3_escape_name(layout.name)
+ cfname = self.cql_protect_name(layout.name)
out.write("CREATE COLUMNFAMILY %s (\n" % cfname)
keycol = layout.columns[0]
- out.write(" %s %s" % (maybe_cql3_escape_name(keycol.name), keycol.cqltype))
+ out.write(" %s %s" % (self.cql_protect_name(keycol.name), keycol.cqltype))
if len(layout.key_components) == 1:
out.write(" PRIMARY KEY")
indexed_columns = []
for col in layout.columns[1:]:
- colname = maybe_cql3_escape_name(col.name)
+ colname = self.cql_protect_name(col.name)
out.write(",\n %s %s" % (colname, col.cqltype))
if col.index_name is not None:
indexed_columns.append(col)
if len(layout.key_components) > 1:
- out.write(",\n PRIMARY KEY (%s)" % ', '.join(map(maybe_cql3_escape_name, layout.key_components)))
+ out.write(",\n PRIMARY KEY (%s)" % ', '.join(map(self.cql_protect_name, layout.key_components)))
out.write("\n)")
joiner = 'WITH'
@@ -1189,13 +1203,13 @@ class Shell(cmd.Cmd):
optval = trim_if_present(optval, 'org.apache.cassandra.cache.')
elif option == 'compaction_strategy_class':
optval = trim_if_present(optval, 'org.apache.cassandra.db.compaction.')
- cf_opts.append((option, cql3_escape_value(optval)))
+ cf_opts.append((option, self.cql_protect_value(optval)))
for option, _ in cql3handling.columnfamily_map_options:
optmap = getattr(layout, option, {})
for k, v in optmap.items():
if option == 'compression_parameters' and k == 'sstable_compression':
v = trim_if_present(v, 'org.apache.cassandra.io.compress.')
- cf_opts.append(('%s:%s' % (option, k.encode('ascii')), cql3_escape_value(v)))
+ cf_opts.append(('%s:%s' % (option, k.encode('ascii')), self.cql_protect_value(v)))
if cf_opts:
for optname, optval in cf_opts:
out.write(" %s\n %s=%s" % (joiner, optname, optval))
@@ -1206,7 +1220,7 @@ class Shell(cmd.Cmd):
out.write('\n')
# guess CQL can't represent index_type or index_options
out.write('CREATE INDEX %s ON %s (%s);\n'
- % (col.index_name, cfname, maybe_cql3_escape_name(col.name)))
+ % (col.index_name, cfname, self.cql_protect_name(col.name)))
def describe_keyspace(self, ksname):
print
@@ -1296,7 +1310,7 @@ class Shell(cmd.Cmd):
what = parsed.matched[1][1].lower()
if what == 'keyspace':
- ksname = cql_dequote(parsed.get_binding('ksname', ''))
+ ksname = self.cql_unprotect_name(parsed.get_binding('ksname', ''))
if not ksname:
ksname = self.current_keyspace
if ksname is None:
@@ -1304,7 +1318,7 @@ class Shell(cmd.Cmd):
return
self.describe_keyspace(ksname)
elif what == 'columnfamily':
- cfname = cql_dequote(parsed.get_binding('cfname'))
+ cfname = self.cql_unprotect_name(parsed.get_binding('cfname'))
self.describe_columnfamily(cfname)
elif what == 'columnfamilies':
self.describe_columnfamilies(self.current_keyspace)
@@ -1387,12 +1401,12 @@ class Shell(cmd.Cmd):
"""
params = {}
- for paramname in ('ks', 'cf', 'colname', 'names', 'values', 'colvalues'):
+ for paramname in ('ks', 'cf', 'colname'):
val = parsed.get_binding(paramname, None)
- if val is not None:
- val = cql_dequote(val)
- params[paramname] = val
-
+ params[paramname] = self.cql_unprotect_name(val)
+ for paramname in ('names', 'values', 'colvalues'):
+ val = parsed.get_binding(paramname, None)
+ params[paramname] = self.cql_unprotect_value(val)
if params['ks'] is None:
if self.current_keyspace is None:
self.printerr('Error: not in any keyspace.')
@@ -1433,7 +1447,7 @@ class Shell(cmd.Cmd):
"""
fname = parsed.get_binding('fname')
- fname = os.path.expanduser(cql_dequote(fname))
+ fname = os.path.expanduser(cqlsh.cql_unprotect_value(fname))
try:
f = open(fname, 'r')
except IOError, e:
@@ -1497,7 +1511,7 @@ class Shell(cmd.Cmd):
' to disable.' % (self.query_out.name,))
return
- fname = os.path.expanduser(cql_dequote(fname))
+ fname = os.path.expanduser(cqlsh.cql_unprotect_value(fname))
try:
f = open(fname, 'a')
except IOError, e:
@@ -1543,7 +1557,7 @@ class Shell(cmd.Cmd):
if not topics:
return cmd.Cmd.do_help(self, '')
for t in topics:
- cmd.Cmd.do_help(self, cql_dequote(t).lower())
+ cmd.Cmd.do_help(self, self.cql_unprotect_value(t).lower())
def help_types(self):
print "\n CQL types recognized by this version of cqlsh:\n"
http://git-wip-us.apache.org/repos/asf/cassandra/blob/f1ee34f0/pylib/cqlshlib/cql3handling.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py
index 9d27f44..a8828ab 100644
--- a/pylib/cqlshlib/cql3handling.py
+++ b/pylib/cqlshlib/cql3handling.py
@@ -16,7 +16,7 @@
import re
from warnings import warn
-from .cqlhandling import cql_typename, cql_escape
+from .cqlhandling import cql_typename, cql_escape, cql_dequote
try:
import json
@@ -66,6 +66,17 @@ def cql3_escape_value(value):
def cql3_escape_name(name):
return '"%s"' % name.replace('"', '""')
+def cql3_dequote_value(value):
+ return cql_dequote(value)
+
+def cql3_dequote_name(name):
+ name = name.strip()
+ if name == '':
+ return name
+ if name[0] == '"':
+ name = name[1:-1].replace('""', '"')
+ return name
+
valid_cql3_word_re = re.compile(r'^[a-z][0-9a-z_]*$', re.I)
def is_valid_cql3_name(s):