diff --git a/bin/cqlsh b/bin/cqlsh index 65f1003f90..30e6505965 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: diff --git a/pylib/cqlshlib/pylexotron.py b/pylib/cqlshlib/pylexotron.py index 0534c87042..e66d2a0cb6 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 = {}