mirror of https://github.com/apache/cassandra
cqlsh: update recognized syntax
Patch by paul cannon and Aleksey Yeschenko, reviewed by brandonwilliams for CASSANDRA-4488
This commit is contained in:
parent
e8438b8084
commit
2f979ed60f
92
bin/cqlsh
92
bin/cqlsh
|
|
@ -441,6 +441,14 @@ class Shell(cmd.Cmd):
|
|||
self.cursor = self.conn.cursor()
|
||||
self.get_connection_versions()
|
||||
|
||||
# use 3.0.0-beta1 syntax if explicitly requested, or if using
|
||||
# cassandra < 1.2. this only affects use of cql3; cql2 syntax
|
||||
# in either case is the same.
|
||||
if self.cassandraver_atleast(1, 2) and not self.is_cql3_beta():
|
||||
cql3handling.use_post_3_0_0_syntax()
|
||||
else:
|
||||
cql3handling.use_pre_3_0_0_syntax()
|
||||
|
||||
self.current_keyspace = keyspace
|
||||
|
||||
self.color = color
|
||||
|
|
@ -473,6 +481,9 @@ class Shell(cmd.Cmd):
|
|||
self.cql_version = ver
|
||||
self.cql_ver_tuple = vertuple
|
||||
|
||||
def is_cql3_beta(self):
|
||||
return self.cql_ver_tuple == (3, 0, 0, 'beta1')
|
||||
|
||||
def cqlver_atleast(self, major, minor=0, patch=0):
|
||||
return self.cql_ver_tuple[:3] >= (major, minor, patch)
|
||||
|
||||
|
|
@ -596,6 +607,11 @@ class Shell(cmd.Cmd):
|
|||
raise ColumnFamilyNotFound("Unconfigured column family %r" % (cfname,))
|
||||
|
||||
def get_columnfamily_names(self, ksname=None):
|
||||
if self.cqlver_atleast(3) and ksname not in SYSTEM_KEYSPACES:
|
||||
# since cql3 tables may be left out of thrift results, but
|
||||
# info on tables in system keyspaces still aren't included
|
||||
# in system.schema_*
|
||||
return self.get_columnfamily_names_cql3(ksname=ksname)
|
||||
return [c.name for c in self.get_columnfamilies(ksname)]
|
||||
|
||||
def get_index_names(self, ksname=None):
|
||||
|
|
@ -681,6 +697,18 @@ class Shell(cmd.Cmd):
|
|||
|
||||
# ===== cql3-dependent parts =====
|
||||
|
||||
def get_columnfamily_names_cql3(self, ksname=None):
|
||||
if ksname is None:
|
||||
ksname = self.current_keyspace
|
||||
if self.cassandraver_atleast(1, 2):
|
||||
cf_q = """select columnfamily_name from system.schema_columnfamilies
|
||||
where keyspace_name=:ks"""
|
||||
else:
|
||||
cf_q = """select "columnfamily" from system.schema_columnfamilies
|
||||
where "keyspace"=:ks"""
|
||||
self.cursor.execute(cf_q, {'ks': ksname})
|
||||
return [row[0] for row in self.cursor.fetchall()]
|
||||
|
||||
def get_columnfamily_layout(self, ksname, cfname):
|
||||
if ksname is None:
|
||||
ksname = self.current_keyspace
|
||||
|
|
@ -853,7 +881,9 @@ class Shell(cmd.Cmd):
|
|||
return self.perform_statement(cqlruleset.cql_extract_orig(tokens, srcstr))
|
||||
|
||||
def handle_parse_error(self, cmdword, tokens, parsed, srcstr):
|
||||
if cmdword.lower() == 'select':
|
||||
if cmdword.lower() in ('select', 'insert', 'update', 'delete', 'truncate',
|
||||
'create', 'drop', 'alter', 'grant', 'revoke',
|
||||
'batch', 'list'):
|
||||
# hey, maybe they know about some new syntax we don't. type
|
||||
# assumptions won't work, but maybe the query will.
|
||||
return self.perform_statement(cqlruleset.cql_extract_orig(tokens, srcstr))
|
||||
|
|
@ -1105,10 +1135,20 @@ class Shell(cmd.Cmd):
|
|||
def print_recreate_keyspace(self, ksdef, out):
|
||||
stratclass = trim_if_present(ksdef.strategy_class, 'org.apache.cassandra.locator.')
|
||||
ksname = self.cql_protect_name(ksdef.name)
|
||||
out.write("CREATE KEYSPACE %s WITH strategy_class = %s"
|
||||
% (ksname, self.cql_protect_value(stratclass)))
|
||||
for opname, opval in ksdef.strategy_options.iteritems():
|
||||
out.write("\n AND strategy_options:%s = %s" % (opname, self.cql_protect_value(opval)))
|
||||
if self.cqlver_atleast(3) and not self.is_cql3_beta():
|
||||
out.write("CREATE KEYSPACE %s WITH replication = {\n" % ksname)
|
||||
out.write(" 'class': %s" % self.cql_protect_value(stratclass))
|
||||
for opname, opval in ksdef.strategy_options.iteritems():
|
||||
out.write(",\n %s: %s" % (self.cql_protect_value(opname),
|
||||
self.cql_protect_value(opval)))
|
||||
out.write("\n}")
|
||||
if not ksdef.durable_writes:
|
||||
out.write(" AND durable_writes = 'false'")
|
||||
else:
|
||||
out.write("CREATE KEYSPACE %s WITH strategy_class = %s"
|
||||
% (ksname, self.cql_protect_value(stratclass)))
|
||||
for opname, opval in ksdef.strategy_options.iteritems():
|
||||
out.write("\n AND strategy_options:%s = %s" % (opname, self.cql_protect_value(opval)))
|
||||
out.write(';\n')
|
||||
|
||||
if ksdef.cf_defs:
|
||||
|
|
@ -1224,24 +1264,42 @@ class Shell(cmd.Cmd):
|
|||
out.write(' WITH COMPACT STORAGE')
|
||||
joiner = 'AND'
|
||||
|
||||
# TODO: this should display CLUSTERING ORDER BY information too.
|
||||
# work out how to determine that from a layout.
|
||||
|
||||
cf_opts = []
|
||||
for option in cqlruleset.columnfamily_layout_options:
|
||||
optval = getattr(layout, option, None)
|
||||
for cql3option, layoutoption in cqlruleset.columnfamily_layout_options:
|
||||
if layoutoption is None:
|
||||
layoutoption = cql3option
|
||||
optval = getattr(layout, layoutoption, None)
|
||||
if optval is None:
|
||||
continue
|
||||
if option == 'row_cache_provider':
|
||||
optval = trim_if_present(optval, 'org.apache.cassandra.cache.')
|
||||
elif option == 'compaction_strategy_class':
|
||||
elif layoutoption == 'compaction_strategy_class':
|
||||
optval = trim_if_present(optval, 'org.apache.cassandra.db.compaction.')
|
||||
cf_opts.append((option, self.cql_protect_value(optval)))
|
||||
for option, _ in cqlruleset.columnfamily_layout_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')), self.cql_protect_value(v)))
|
||||
cf_opts.append((cql3option, self.cql_protect_value(optval)))
|
||||
for cql3option, layoutoption, _ in cqlruleset.columnfamily_layout_map_options:
|
||||
if layoutoption is None:
|
||||
layoutoption = cql3option
|
||||
optmap = getattr(layout, layoutoption, {})
|
||||
if layoutoption == 'compression_parameters':
|
||||
compclass = optmap.get('sstable_compression')
|
||||
if compclass is not None:
|
||||
optmap['sstable_compression'] = \
|
||||
trim_if_present(compclass, 'org.apache.cassandra.io.compress.')
|
||||
if self.cqlver_atleast(3) and not self.is_cql3_beta():
|
||||
cf_opts.append((cql3option, optmap))
|
||||
else:
|
||||
for k, v in optmap.items():
|
||||
cf_opts.append(('%s:%s' % (cql3option, k.encode('ascii')),
|
||||
self.cql_protect_value(v)))
|
||||
if cf_opts:
|
||||
for optname, optval in cf_opts:
|
||||
if isinstance(optval, dict):
|
||||
optval = '{%s}' % ', '.join(['%s: %s' % (self.cql_protect_value(k),
|
||||
self.cql_protect_value(v))
|
||||
for (k, v) in optval.items()])
|
||||
if optval == '{}':
|
||||
continue
|
||||
out.write(" %s\n %s=%s" % (joiner, optname, optval))
|
||||
joiner = 'AND'
|
||||
out.write(";\n")
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -24,6 +24,8 @@ from cql import cqltypes
|
|||
|
||||
Hint = pylexotron.Hint
|
||||
|
||||
SYSTEM_KEYSPACES = ('system',)
|
||||
|
||||
class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
|
||||
keywords = set((
|
||||
'select', 'from', 'where', 'and', 'key', 'insert', 'update', 'with',
|
||||
|
|
@ -84,6 +86,13 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
|
|||
'NetworkTopologyStrategy'
|
||||
)
|
||||
|
||||
replication_factor_strategies = (
|
||||
'SimpleStrategy',
|
||||
'org.apache.cassandra.locator.SimpleStrategy',
|
||||
'OldNetworkTopologyStrategy',
|
||||
'org.apache.cassandra.locator.OldNetworkTopologyStrategy'
|
||||
)
|
||||
|
||||
consistency_levels = (
|
||||
'ANY',
|
||||
'ONE',
|
||||
|
|
@ -385,7 +394,7 @@ class CqlParsingRuleSet(pylexotron.ParsingRuleSet):
|
|||
cqlword = cqlword.strip()
|
||||
if cqlword == '':
|
||||
return cqlword
|
||||
if cqlword[0] == "'":
|
||||
if cqlword[0] == "'" and cqlword[-1] == "'":
|
||||
cqlword = cqlword[1:-1].replace("''", "'")
|
||||
return cqlword
|
||||
|
||||
|
|
@ -736,10 +745,7 @@ def create_ks_opt_completer(ctxt, cass):
|
|||
return ['strategy_class =']
|
||||
vals = ctxt.get_binding('optval')
|
||||
stratclass = dequote_value(vals[stratopt])
|
||||
if stratclass in ('SimpleStrategy',
|
||||
'org.apache.cassandra.locator.SimpleStrategy',
|
||||
'OldNetworkTopologyStrategy',
|
||||
'org.apache.cassandra.locator.OldNetworkTopologyStrategy'):
|
||||
if stratclass in CqlRuleSet.replication_factor_strategies:
|
||||
return ['strategy_options:replication_factor =']
|
||||
return [Hint('<strategy_option_name>')]
|
||||
|
||||
|
|
|
|||
|
|
@ -118,19 +118,24 @@ class matcher:
|
|||
|
||||
@staticmethod
|
||||
def try_registered_completion(ctxt, symname, completions):
|
||||
debugging = ctxt.get_binding('*DEBUG*', False)
|
||||
if ctxt.remainder or completions is None:
|
||||
return False
|
||||
try:
|
||||
completer = ctxt.get_completer(symname)
|
||||
except KeyError:
|
||||
return False
|
||||
if debugging:
|
||||
print "Trying completer %r with %r" % (completer, ctxt)
|
||||
try:
|
||||
new_compls = completer(ctxt)
|
||||
except Exception:
|
||||
if ctxt.get_binding('*DEBUG*', False):
|
||||
if debugging:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
if debugging:
|
||||
print "got %r" % (new_compls,)
|
||||
completions.update(new_compls)
|
||||
return True
|
||||
|
||||
|
|
@ -291,6 +296,9 @@ class terminal_type_matcher(matcher):
|
|||
self.submatcher.match(ctxt, completions)
|
||||
return []
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%r, %r)' % (self.__class__.__name__, self.tokentype, self.submatcher)
|
||||
|
||||
class ParsingRuleSet:
|
||||
RuleSpecScanner = SaferScanner([
|
||||
(r'::=', lambda s,t: t),
|
||||
|
|
|
|||
Loading…
Reference in New Issue