Repository: cassandra Updated Branches: refs/heads/cassandra-3.0 e6f23e63c -> aeee9f74d
Add DESCRIBE MATERIALIZED VIEW to cqlsh patch by Stefania Alborghetti; reviewed by Benjamin Lerer for CASSANDRA-9961 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/aeee9f74 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/aeee9f74 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/aeee9f74 Branch: refs/heads/cassandra-3.0 Commit: aeee9f74d9095a802a23f1a47be021ede6fb65bc Parents: e6f23e6 Author: Stefania Alborghetti <[email protected]> Authored: Fri Sep 18 11:33:54 2015 +0200 Committer: blerer <[email protected]> Committed: Fri Sep 18 11:33:54 2015 +0200 ---------------------------------------------------------------------- bin/cqlsh.py | 79 +++++++++++++++++-- ...iver-internal-only-3.0.0a2.post0-03085e6.zip | Bin 0 -> 230830 bytes ...iver-internal-only-3.0.0a2.post0-9f91a6d.zip | Bin 230797 -> 0 bytes pylib/cqlshlib/cql3handling.py | 24 +++++- .../cassandra/service/MigrationListener.java | 1 + 5 files changed, 96 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/aeee9f74/bin/cqlsh.py ---------------------------------------------------------------------- diff --git a/bin/cqlsh.py b/bin/cqlsh.py index 529b1c8..41fa4fd 100644 --- a/bin/cqlsh.py +++ b/bin/cqlsh.py @@ -289,12 +289,13 @@ cqlsh_extra_syntax_rules = r''' | "KEYSPACE" ksname=<keyspaceName>? | ( "COLUMNFAMILY" | "TABLE" ) cf=<columnFamilyName> | "INDEX" idx=<indexName> + | "MATERIALIZED" "VIEW" mv=<materializedViewName> | ( "COLUMNFAMILIES" | "TABLES" ) | "FULL"? "SCHEMA" | "CLUSTER" | "TYPES" | "TYPE" ut=<userTypeName> - | (ksname=<keyspaceName> | cf=<columnFamilyName> | idx=<indexName>)) + | (ksname=<keyspaceName> | cf=<columnFamilyName> | idx=<indexName> | mv=<materializedViewName>)) ; <consistencyCommand> ::= "CONSISTENCY" ( level=<consistencyLevel> )? @@ -459,6 +460,10 @@ class IndexNotFound(Exception): pass +class MaterializedViewNotFound(Exception): + pass + + class ObjectNotFound(Exception): pass @@ -792,6 +797,12 @@ class Shell(cmd.Cmd): return map(str, self.get_keyspace_meta(ksname).tables.keys()) + def get_materialized_view_names(self, ksname=None): + if ksname is None: + ksname = self.current_keyspace + + return map(str, self.get_keyspace_meta(ksname).views.keys()) + def get_index_names(self, ksname=None): if ksname is None: ksname = self.current_keyspace @@ -898,6 +909,15 @@ class Shell(cmd.Cmd): return ksmeta.indexes[idxname] + def get_view_meta(self, ksname, viewname): + if ksname is None: + ksname = self.current_keyspace + ksmeta = self.get_keyspace_meta(ksname) + + if viewname not in ksmeta.views: + raise MaterializedViewNotFound("Materialized view %r not found" % viewname) + return ksmeta.views[viewname] + def get_object_meta(self, ks, name): if name is None: if ks and ks in self.conn.metadata.keyspaces: @@ -917,6 +937,8 @@ class Shell(cmd.Cmd): return ksmeta.tables[name] elif name in ksmeta.indexes: return ksmeta.indexes[name] + elif name in ksmeta.views: + return ksmeta.views[name] raise ObjectNotFound("%r not found in keyspace %r" % (name, ks)) @@ -1151,7 +1173,22 @@ class Shell(cmd.Cmd): return result - def parse_for_table_meta(self, query_string): + def parse_for_select_meta(self, query_string): + try: + parsed = cqlruleset.cql_parse(query_string)[1] + except IndexError: + return None + ks = self.cql_unprotect_name(parsed.get_binding('ksname', None)) + name = self.cql_unprotect_name(parsed.get_binding('cfname', None)) + try: + return self.get_table_meta(ks, name) + except ColumnFamilyNotFound: + try: + return self.get_view_meta(ks, name) + except MaterializedViewNotFound: + raise ObjectNotFound("%r not found in keyspace %r" % (name, ks)) + + def parse_for_update_meta(self, query_string): try: parsed = cqlruleset.cql_parse(query_string)[1] except IndexError: @@ -1182,7 +1219,7 @@ class Shell(cmd.Cmd): return False, None if statement.query_string[:6].lower() == 'select': - self.print_result(rows, self.parse_for_table_meta(statement.query_string)) + self.print_result(rows, self.parse_for_select_meta(statement.query_string)) elif statement.query_string.lower().startswith("list users") or statement.query_string.lower().startswith("list roles"): self.print_result(rows, self.get_table_meta('system_auth', 'roles')) elif statement.query_string.lower().startswith("list"): @@ -1190,7 +1227,7 @@ class Shell(cmd.Cmd): elif rows: # CAS INSERT/UPDATE self.writeresult("") - self.print_static_result(rows, self.parse_for_table_meta(statement.query_string)) + self.print_static_result(rows, self.parse_for_update_meta(statement.query_string)) self.flush_output() return True, future @@ -1369,6 +1406,16 @@ class Shell(cmd.Cmd): out.write(self.get_index_meta(ksname, idxname).export_as_string()) out.write("\n") + def print_recreate_materialized_view(self, ksname, viewname, out): + """ + Output CQL commands which should be pasteable back into a CQL session + to recreate the given materialized view. + + Writes output to the given out stream. + """ + out.write(self.get_view_meta(ksname, viewname).export_as_string()) + out.write("\n") + def print_recreate_object(self, ks, name, out): """ Output CQL commands which should be pasteable back into a CQL session @@ -1403,6 +1450,15 @@ class Shell(cmd.Cmd): self.print_recreate_index(ksname, idxname, sys.stdout) print + def describe_materialized_view(self, ksname, viewname): + if ksname is None: + ksname = self.current_keyspace + if ksname is None: + raise NoKeyspaceError("No keyspace specified and no current keyspace") + print + self.print_recreate_materialized_view(ksname, viewname, sys.stdout) + print + def describe_object(self, ks, name): print self.print_recreate_object(ks, name, sys.stdout) @@ -1564,6 +1620,12 @@ class Shell(cmd.Cmd): In some cases, there may be index metadata which is not representable and which will not be shown. + DESCRIBE MATERIALIZED VIEW <viewname> + + Output CQL commands that could be used to recreate the given materialized view. + In some cases, there may be materialized view metadata which is not representable + and which will not be shown. + DESCRIBE CLUSTER Output information about the connected Cassandra cluster, such as the @@ -1596,7 +1658,8 @@ class Shell(cmd.Cmd): DESCRIBE <objname> Output CQL commands that could be used to recreate the entire object schema, - where object can be either a keyspace or a table or an index (in this order). + where object can be either a keyspace or a table or an index or a materialized + view (in this order). """ what = parsed.matched[1][1].lower() if what == 'functions': @@ -1631,6 +1694,10 @@ class Shell(cmd.Cmd): ks = self.cql_unprotect_name(parsed.get_binding('ksname', None)) idx = self.cql_unprotect_name(parsed.get_binding('idxname', None)) self.describe_index(ks, idx) + elif what == 'materialized' and parsed.matched[2][1].lower() == 'view': + ks = self.cql_unprotect_name(parsed.get_binding('ksname', None)) + mv = self.cql_unprotect_name(parsed.get_binding('mvname')) + self.describe_materialized_view(ks, mv) elif what in ('columnfamilies', 'tables'): self.describe_columnfamilies(self.current_keyspace) elif what == 'types': @@ -1650,6 +1717,8 @@ class Shell(cmd.Cmd): name = self.cql_unprotect_name(parsed.get_binding('cfname')) if not name: name = self.cql_unprotect_name(parsed.get_binding('idxname', None)) + if not name: + name = self.cql_unprotect_name(parsed.get_binding('mvname', None)) self.describe_object(ks, name) do_desc = do_describe http://git-wip-us.apache.org/repos/asf/cassandra/blob/aeee9f74/lib/cassandra-driver-internal-only-3.0.0a2.post0-03085e6.zip ---------------------------------------------------------------------- diff --git a/lib/cassandra-driver-internal-only-3.0.0a2.post0-03085e6.zip b/lib/cassandra-driver-internal-only-3.0.0a2.post0-03085e6.zip new file mode 100644 index 0000000..e672bd9 Binary files /dev/null and b/lib/cassandra-driver-internal-only-3.0.0a2.post0-03085e6.zip differ http://git-wip-us.apache.org/repos/asf/cassandra/blob/aeee9f74/lib/cassandra-driver-internal-only-3.0.0a2.post0-9f91a6d.zip ---------------------------------------------------------------------- diff --git a/lib/cassandra-driver-internal-only-3.0.0a2.post0-9f91a6d.zip b/lib/cassandra-driver-internal-only-3.0.0a2.post0-9f91a6d.zip deleted file mode 100644 index ff4d150..0000000 Binary files a/lib/cassandra-driver-internal-only-3.0.0a2.post0-9f91a6d.zip and /dev/null differ http://git-wip-us.apache.org/repos/asf/cassandra/blob/aeee9f74/pylib/cqlshlib/cql3handling.py ---------------------------------------------------------------------- diff --git a/pylib/cqlshlib/cql3handling.py b/pylib/cqlshlib/cql3handling.py index e4b2bfa..94b132f 100644 --- a/pylib/cqlshlib/cql3handling.py +++ b/pylib/cqlshlib/cql3handling.py @@ -283,6 +283,8 @@ JUNK ::= /([ \t\r\f\v]+|(--|[/][/])[^\n\r]*([\n\r]|$)|[/][*].*?[*][/])/ ; <columnFamilyName> ::= ( ksname=<cfOrKsName> dot="." )? cfname=<cfOrKsName> ; +<materializedViewName> ::= ( ksname=<cfOrKsName> dot="." )? mvname=<cfOrKsName> ; + <userTypeName> ::= ( ksname=<cfOrKsName> dot="." )? utname=<cfOrKsName> ; <keyspaceName> ::= ksname=<cfOrKsName> ; @@ -559,6 +561,7 @@ def cf_ks_name_completer(ctxt, cass): return [maybe_escape_name(ks) + '.' for ks in cass.get_keyspace_names()] completer_for('columnFamilyName', 'ksname')(cf_ks_name_completer) +completer_for('materializedViewName', 'ksname')(cf_ks_name_completer) def cf_ks_dot_completer(ctxt, cass): @@ -568,6 +571,7 @@ def cf_ks_dot_completer(ctxt, cass): return [] completer_for('columnFamilyName', 'dot')(cf_ks_dot_completer) +completer_for('materializedViewName', 'dot')(cf_ks_dot_completer) @completer_for('columnFamilyName', 'cfname') @@ -583,6 +587,20 @@ def cf_name_completer(ctxt, cass): raise return map(maybe_escape_name, cfnames) + +@completer_for('materializedViewName', 'mvname') +def mv_name_completer(ctxt, cass): + ks = ctxt.get_binding('ksname', None) + if ks is not None: + ks = dequote_name(ks) + try: + mvnames = cass.get_materialized_view_names(ks) + except Exception: + if ks is None: + return () + raise + return map(maybe_escape_name, mvnames) + completer_for('userTypeName', 'ksname')(cf_ks_name_completer) completer_for('userTypeName', 'dot')(cf_ks_dot_completer) @@ -639,7 +657,7 @@ syntax_rules += r''' <useStatement> ::= "USE" <keyspaceName> ; <selectStatement> ::= "SELECT" ( "JSON" )? <selectClause> - "FROM" cf=<columnFamilyName> + "FROM" (cf=<columnFamilyName> | mv=<materializedViewName>) ( "WHERE" <whereClause> )? ( "ORDER" "BY" <orderByClause> ( "," <orderByClause> )* )? ( "LIMIT" limit=<wholenumber> )? @@ -1133,7 +1151,7 @@ syntax_rules += r''' ( "USING" <stringLiteral> ( "WITH" "OPTIONS" "=" <mapLiteral> )? )? ; -<createMaterializedViewStatement> ::= "CREATE" "MATERIALIZED" "VIEW" ("IF" "NOT" "EXISTS")? <columnFamilyName>? +<createMaterializedViewStatement> ::= "CREATE" "MATERIALIZED" "VIEW" ("IF" "NOT" "EXISTS")? <materializedViewName>? "AS" <selectStatement> "PRIMARY" "KEY" <pkDef> ; @@ -1195,7 +1213,7 @@ syntax_rules += r''' <dropIndexStatement> ::= "DROP" "INDEX" ("IF" "EXISTS")? idx=<indexName> ; -<dropMaterializedViewStatement> ::= "DROP" "MATERIALIZED" "VIEW" ("IF" "EXISTS")? mv=<columnFamilyName> +<dropMaterializedViewStatement> ::= "DROP" "MATERIALIZED" "VIEW" ("IF" "EXISTS")? mv=<materializedViewName> ; <dropUserTypeStatement> ::= "DROP" "TYPE" ut=<userTypeName> http://git-wip-us.apache.org/repos/asf/cassandra/blob/aeee9f74/src/java/org/apache/cassandra/service/MigrationListener.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/service/MigrationListener.java b/src/java/org/apache/cassandra/service/MigrationListener.java index f4b3e7c..9e240ea 100644 --- a/src/java/org/apache/cassandra/service/MigrationListener.java +++ b/src/java/org/apache/cassandra/service/MigrationListener.java @@ -83,6 +83,7 @@ public abstract class MigrationListener public void onDropView(String ksName, String viewName) { + onDropColumnFamily(ksName, viewName); } public void onDropUserType(String ksName, String typeName)
