cqlsh: suggesting cql3 to cql2 users when they get an error and their statement appears to parse for cql 2, and vice versa. Patch by paul cannon, reviewed by brandonwilliams for CASSANDRA-4454
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/5a63858d Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/5a63858d Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/5a63858d Branch: refs/heads/trunk Commit: 5a63858d0d9896baab66b12f2d83f424e5c0fbfa Parents: 1e6cc9a Author: Brandon Williams <brandonwilli...@apache.org> Authored: Thu Sep 13 14:01:41 2012 -0500 Committer: Brandon Williams <brandonwilli...@apache.org> Committed: Thu Sep 13 14:01:41 2012 -0500 ---------------------------------------------------------------------- bin/cqlsh | 23 +++++++++++++++++++++++ pylib/cqlshlib/pylexotron.py | 4 ++++ 2 files changed, 27 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/5a63858d/bin/cqlsh ---------------------------------------------------------------------- diff --git a/bin/cqlsh b/bin/cqlsh index 65f1003..30e6505 100755 --- a/bin/cqlsh +++ b/bin/cqlsh @@ -1027,6 +1027,18 @@ class Shell(cmd.Cmd): if trynum > self.num_retries: return False time.sleep(1*trynum) + except cql.ProgrammingError, err: + self.printerr(str(err)) + # try reparsing as cql3; if successful, suggest -3 + if self.cqlver_atleast(3): + if self.parseable_as_cql2(statement): + self.printerr("Perhaps you meant to use CQL 2? Try using" + " the -2 option when starting cqlsh.") + else: + if self.parseable_as_cql3(statement): + self.printerr("Perhaps you meant to use CQL 3? Try using" + " the -3 option when starting cqlsh.") + return False except CQL_ERRORS, err: self.printerr(str(err)) return False @@ -1041,6 +1053,17 @@ class Shell(cmd.Cmd): self.print_result(self.cursor) return True + # these next two functions are not guaranteed perfect; just checks if the + # statement parses fully according to cqlsh's own understanding of the + # grammar. Changes to the language in Cassandra frequently don't get + # updated in cqlsh right away. + + def parseable_as_cql3(self, statement): + return cql3handling.CqlRuleSet.lex_and_whole_match(statement) is not None + + def parseable_as_cql2(self, statement): + return cqlhandling.CqlRuleSet.lex_and_whole_match(statement) is not None + def determine_decoder_for(self, cfname, ksname=None): decoder = ErrorHandlingSchemaDecoder if ksname is None: http://git-wip-us.apache.org/repos/asf/cassandra/blob/5a63858d/pylib/cqlshlib/pylexotron.py ---------------------------------------------------------------------- diff --git a/pylib/cqlshlib/pylexotron.py b/pylib/cqlshlib/pylexotron.py index 0534c87..e66d2a0 100644 --- a/pylib/cqlshlib/pylexotron.py +++ b/pylib/cqlshlib/pylexotron.py @@ -446,6 +446,10 @@ class ParsingRuleSet: def lex_and_parse(self, text, startsymbol='Start'): return self.parse(startsymbol, self.lex(text), init_bindings={'*SRC*': text}) + def lex_and_whole_match(self, text, startsymbol='Start'): + tokens = self.lex(text) + return self.whole_match(startsymbol, tokens, srcstr=text) + def complete(self, startsymbol, tokens, init_bindings=None): if init_bindings is None: init_bindings = {}