Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master 67f7f3e40 -> b9583c6e0


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
----------------------------------------------------------------------
diff --git 
a/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html 
b/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
new file mode 100644
index 0000000..5c4546f
--- /dev/null
+++ b/cassandra/src/test/resources/scalate/DescribeType_live_data_address.html
@@ -0,0 +1,137 @@
+<br/>
+<br/>
+<nav class="navbar navbar-default">
+    <ul class="nav navbar-nav">
+
+        <li>
+            <a><strong>DESCRIBE TYPE live_data.address;</strong></a>
+        </li>
+    </ul>
+    <ul class="nav navbar-nav navbar-right">
+        <li class="dropdown">
+            <a class="dropdown-toggle" data-toggle="dropdown" role="button" 
aria-haspopup="true" aria-expanded="false">
+                <strong>Legend</strong>
+                <span class="caret"></span>
+            </a>
+            <ul class="dropdown-menu">
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-dashboard text-muted" 
/>&nbsp;Cluster
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-folder-open text-danger" 
/>&nbsp;&nbsp;Keyspace
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-copyright-mark 
text-warning" />&nbsp;&nbsp;UDT
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-th-list text-primary" 
/>&nbsp;&nbsp;Table
+                    </a>
+                </li>
+                <li class="bg-info">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-fullscreen" 
/>&nbsp;&nbsp;Partition Key
+                    </a>
+                </li>
+                <li class="bg-warning">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-pushpin" 
/>&nbsp;&nbsp;Static Column
+                    </a>
+                </li>
+                <li class="bg-success">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-sort" 
/>&nbsp;&nbsp;Clustering Column
+                    </a>
+                </li>
+                <li class="bg-success">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-sort-by-attributes" 
/>&nbsp;&nbsp;Clustering Order ASC
+                    </a>
+                </li>
+                <li class="bg-success">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-sort-by-attributes-alt" 
/>&nbsp;&nbsp;Clustering Order DESC
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-info-sign" 
/>&nbsp;&nbsp;Indexed Column
+                    </a>
+                </li>
+            </ul>
+        </li>
+        <li>
+            <a href="#"></a>
+        </li>
+    </ul>
+</nav>
+<hr/>
+<div class="row">
+    <div class="col-md-3"></div>
+    <div class="col-md-6 col-offset-md-3">
+        <div class="panel panel-default table-responsive table-bordered">
+            <table class="table">
+
+                <caption><h4 class="text-warning"><i class="glyphicon 
glyphicon-copyright-mark"/>&nbsp;address</h4></caption>
+
+                <thead>
+                <tr>
+                    <th class="col-md-6">Column Name</th>
+                    <th class="col-md-6">Data Type</th>
+                </tr>
+                </thead>
+                <tbody>
+
+                <tr>
+                    <td class="col-md-6">number</td>
+                    <td class="col-md-6">int</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">street</td>
+                    <td class="col-md-6">text</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">zip</td>
+                    <td class="col-md-6">int</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">city</td>
+                    <td class="col-md-6">text</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">country</td>
+                    <td class="col-md-6">text</td>
+                </tr>
+
+                <tbody>
+            </table>
+            <div class="panel-footer">
+                <a data-toggle="collapse" 
data-target="#984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
+                    <strong>As CQL statement</strong>
+                    <span class="caret"></span>
+                </a>
+                <br/><br/>
+                <div class="collapse" 
id="984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
+                    <pre class="well">CREATE TYPE live_data.address (
+    number int,
+    street text,
+    zip int,
+    city text,
+    country text
+);</pre>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="col-md-3"></div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
----------------------------------------------------------------------
diff --git 
a/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
 
b/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
new file mode 100644
index 0000000..aa657f9
--- /dev/null
+++ 
b/cassandra/src/test/resources/scalate/DescribeType_live_data_address_within_current_keyspace.html
@@ -0,0 +1,137 @@
+<br/>
+<br/>
+<nav class="navbar navbar-default">
+    <ul class="nav navbar-nav">
+
+        <li>
+            <a><strong>DESCRIBE TYPE address;</strong></a>
+        </li>
+    </ul>
+    <ul class="nav navbar-nav navbar-right">
+        <li class="dropdown">
+            <a class="dropdown-toggle" data-toggle="dropdown" role="button" 
aria-haspopup="true" aria-expanded="false">
+                <strong>Legend</strong>
+                <span class="caret"></span>
+            </a>
+            <ul class="dropdown-menu">
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-dashboard text-muted" 
/>&nbsp;Cluster
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-folder-open text-danger" 
/>&nbsp;&nbsp;Keyspace
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-copyright-mark 
text-warning" />&nbsp;&nbsp;UDT
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-th-list text-primary" 
/>&nbsp;&nbsp;Table
+                    </a>
+                </li>
+                <li class="bg-info">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-fullscreen" 
/>&nbsp;&nbsp;Partition Key
+                    </a>
+                </li>
+                <li class="bg-warning">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-pushpin" 
/>&nbsp;&nbsp;Static Column
+                    </a>
+                </li>
+                <li class="bg-success">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-sort" 
/>&nbsp;&nbsp;Clustering Column
+                    </a>
+                </li>
+                <li class="bg-success">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-sort-by-attributes" 
/>&nbsp;&nbsp;Clustering Order ASC
+                    </a>
+                </li>
+                <li class="bg-success">
+                    <a role="button">
+                        <i class="glyphicon glyphicon-sort-by-attributes-alt" 
/>&nbsp;&nbsp;Clustering Order DESC
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <i class="glyphicon glyphicon-info-sign" 
/>&nbsp;&nbsp;Indexed Column
+                    </a>
+                </li>
+            </ul>
+        </li>
+        <li>
+            <a href="#"></a>
+        </li>
+    </ul>
+</nav>
+<hr/>
+<div class="row">
+    <div class="col-md-3"></div>
+    <div class="col-md-6 col-offset-md-3">
+        <div class="panel panel-default table-responsive table-bordered">
+            <table class="table">
+
+                <caption><h4 class="text-warning"><i class="glyphicon 
glyphicon-copyright-mark"/>&nbsp;address</h4></caption>
+
+                <thead>
+                <tr>
+                    <th class="col-md-6">Column Name</th>
+                    <th class="col-md-6">Data Type</th>
+                </tr>
+                </thead>
+                <tbody>
+
+                <tr>
+                    <td class="col-md-6">number</td>
+                    <td class="col-md-6">int</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">street</td>
+                    <td class="col-md-6">text</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">zip</td>
+                    <td class="col-md-6">int</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">city</td>
+                    <td class="col-md-6">text</td>
+                </tr>
+
+                <tr>
+                    <td class="col-md-6">country</td>
+                    <td class="col-md-6">text</td>
+                </tr>
+
+                <tbody>
+            </table>
+            <div class="panel-footer">
+                <a data-toggle="collapse" 
data-target="#984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
+                    <strong>As CQL statement</strong>
+                    <span class="caret"></span>
+                </a>
+                <br/><br/>
+                <div class="collapse" 
id="984da320-350d-11e5-a7a9-8f0ea8ae1a37_asCQL">
+                    <pre class="well">CREATE TYPE live_data.address (
+    number int,
+    street text,
+    zip int,
+    city text,
+    country text
+);</pre>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div class="col-md-3"></div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/resources/scalate/Help.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/Help.html 
b/cassandra/src/test/resources/scalate/Help.html
new file mode 100644
index 0000000..de71d64
--- /dev/null
+++ b/cassandra/src/test/resources/scalate/Help.html
@@ -0,0 +1,870 @@
+<br/>
+<br/>
+<nav class="navbar navbar-default">
+    <ul class="nav navbar-nav">
+        <li role="presentation" class="dropdown">
+            <a class="dropdown-toggle" data-toggle="dropdown" role="button" 
aria-haspopup="true" aria-expanded="false">
+                <span class="text-info"><i class="glyphicon 
glyphicon-book"/>&nbsp;<strong>Please select ...</strong></span>
+                <span class="text-info caret"></span>
+                <ul class="dropdown-menu">
+                    <li class="dropdown-header"><span 
class="text-info">Topics</span></li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#d977b63a-9900-4ecd-a438-70eb490d6a48">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Basic Commands</span>
+                        </a>
+                    </li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#eb22d00b-9be8-478a-b4bf-740f98e1e6ec">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Schema Discovery</span>
+                        </a>
+                    </li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#881a5e0b-5e52-4474-ba80-787dfe0a770d">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Query Parameters</span>
+                        </a>
+                    </li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#2af5a125-8754-40fb-a044-bda10395504f">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Prepared Statements</span>
+                        </a>
+                    </li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#4dfe08e1-7ee0-4222-8be0-3d9d43aab38e">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Dynamic Forms</span>
+                        </a>
+                    </li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#6485679a-ab5b-406b-8281-37f586459754">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Interpreter Configuration</span>
+                        </a>
+                    </li>
+                    <li>
+                        <a role="button" data-toggle="collapse" 
data-target="#2d060cba-7f9a-40de-8cc3-d82586d4321e">
+                            <span class="text-info"><i class="glyphicon 
glyphicon-bookmark"/>&nbsp;&nbsp;Misc</span>
+                        </a>
+                    </li>
+                </ul>
+            </a>
+        </li>
+
+        <li>
+            <a><span class="text-info"><strong>CASSANDRA INTERPRETER 
DOCUMENTATION</strong></span></a>
+        </li>
+    </ul>
+    <ul class="nav navbar-nav navbar-right">
+        <li class="dropdown">
+            <a class="dropdown-toggle" data-toggle="dropdown" role="button" 
aria-haspopup="true" aria-expanded="false">
+                <span class="text-info"><strong>About ...</strong></span>
+                <span class="caret"></span>
+            </a>
+            <ul class="dropdown-menu">
+                <li>
+                    <a role="button">
+                        <span class="text-info">Version 
<strong>1.0</strong></span>
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <span class="text-info">Java Driver Version 
<strong>2.1.7.1</strong></span>
+                    </a>
+                </li>
+                <li>
+                    <a role="button">
+                        <span class="text-info">Author 
<strong>@doanduyhai</strong></span>
+                    </a>
+                </li>
+            </ul>
+        </li>
+        <li>
+            <a href="#"></a>
+        </li>
+</nav>
+<br/><br/>
+<div class="container">
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#d977b63a-9900-4ecd-a438-70eb490d6a48" aria-expanded="false">
+                    <span class="text-info"><strong>Basic 
Commands</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="d977b63a-9900-4ecd-a438-70eb490d6a48" class="panel-collapse 
collapse in" role="tabpanel">
+            <div class="panel-body">
+
+                <div class="panel panel-default">
+                    <div class="panel-body">
+                        <h3>I CQL Statements</h3>
+                        <p>This interpreter is compatible with any CQL 
statement supported by Cassandra. Ex:
+                            <br/><br/>
+                        <div class="row">
+                            <div class="col-md-6 col-md-offset-3">
+                                <pre>
+
+    INSERT INTO users(login,name) VALUES('jdoe','John DOE');
+    SELECT * FROM users WHERE login='jdoe';
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+                        Each statement should be separated by a 
<strong>semi-colon</strong> (;).
+                        <br/>
+                        <strong>Multi-line</strong> statements as well as 
multiple statements on the <strong>same line</strong>
+                        are also supported as long as they are separated by a 
semi-colon. Ex:
+                        <br/>
+                        <br/>
+                        <div class="row">
+                            <div class="col-md-8 col-md-offset-2">
+                                <pre>
+
+    USE spark_demo;
+
+    SELECT * FROM albums_by_country LIMIT 1; SELECT * FROM countries LIMIT 1;
+
+    SELECT *
+    FROM artists
+    WHERE login='jlennon';
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+                        <strong>Batch</strong> statements are supported and 
can span multiple lines, as well as
+                        <strong>DDL</strong>(CREATE/ALTER/DROP) statements:
+                        <br/>
+                        <br/>
+                        <div class="row">
+                            <div class="col-md-8 col-md-offset-2">
+                                <pre>
+
+    BEGIN BATCH
+        INSERT INTO users(login,name) VALUES('jdoe','John DOE');
+        INSERT INTO users_preferences(login,account_type) 
VALUES('jdoe','BASIC');
+    APPLY BATCH;
+
+    CREATE TABLE IF NOT EXISTS test(
+        key int PRIMARY KEY,
+        value text
+    );
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+                        CQL statements are <strong>case-insensitive</strong> 
(except for column names and values).
+                        This means that the following statements are 
equivalent and valid:
+                        <br/>
+                        <br/>
+                        <div class="row">
+                            <div class="col-md-8 col-md-offset-2">
+                                <pre>
+
+    INSERT INTO users(login,name) VALUES('jdoe','John DOE');
+    Insert into users(login,name) vAlues('hsue','Helen SUE');
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+                        The complete list of all CQL statements and versions 
can be found below:
+                        <br/><br/>
+                        <div class="row">
+                            <div class="col-md-6 col-md-offset-3">
+                                <table class="table table-bordered">
+                                    <thead>
+                                    <tr><th>Cassandra 
version</th><th>Documentation</th></tr>
+                                    </thead>
+                                    <tbody>
+                                    <tr>
+                                        <td><strong>2.2</strong></td>
+                                        <td>
+                                            <a 
href="http://docs.datastax.com/en/cql/3.3/cql/cqlIntro.html"; target="_blank">
+                                                
http://docs.datastax.com/en/cql/3.3/cql/cqlIntro.html
+                                            </a>
+                                        </td>
+                                    </tr>
+                                    <tr>
+                                        <td><strong>2.1 & 2.0</strong></td>
+                                        <td>
+                                            <a 
href="http://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html"; target="_blank">
+                                                
http://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html
+                                            </a>
+                                        </td>
+                                    </tr>
+                                    <tr>
+                                        <td><strong>1.2</strong></td>
+                                        <td>
+                                            <a 
href="http://docs.datastax.com/en/cql/3.0/cql/aboutCQL.html"; target="_blank">
+                                                
http://docs.datastax.com/en/cql/3.0/cql/aboutCQL.html
+                                            </a>
+                                        </td>
+                                    </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+
+
+                        </p>
+                        <h3>II Comments</h3>
+                        <p>
+                            It is possible to add comments between statements. 
Single line comments start with the
+                            <strong>hash</strong> sign (#). Multi-line 
comments are enclosed between
+                            <strong>&sol;&ast;&ast;</strong> and 
<strong>&ast;&ast;&sol;</strong>. Ex:
+
+                            <br/>
+                            <br/>
+                        <div class="row">
+                            <div class="col-md-8 col-md-offset-2">
+                                <pre>
+
+    #First comment
+    INSERT INTO users(login,name) VALUES('jdoe','John DOE');
+
+    /**
+     Multi line
+     comments
+     **/
+    Insert into users(login,name) vAlues('hsue','Helen SUE');
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+
+                        </p>
+                        <h3>III Syntax Validation</h3>
+                        <p>
+                            The interpreters is shipped with a <em>built-in 
syntax validator</em>. This validator only
+                            checks for <strong>basic syntax errors</strong>. 
All CQL-related syntax validation is delegated
+                            directly to <strong>Cassandra</strong>
+                            <br/><br/>
+                            Most of the time, syntax errors are due to missing 
semi-colons between statements or typo errors.
+
+                        </p>
+
+                    </div>
+                </div>
+
+
+
+            </div>
+        </div>
+    </div>
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#eb22d00b-9be8-478a-b4bf-740f98e1e6ec" aria-expanded="false">
+                    <span class="text-info"><strong>Schema 
Discovery</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="eb22d00b-9be8-478a-b4bf-740f98e1e6ec" class="panel-collapse 
collapse" role="tabpanel">
+            <div class="panel-body">
+
+                <div class="panel panel-default">
+                    <div class="panel-body">
+                        <h3>I Commands For Discovery</h3>
+                        <p>
+                            To make schema discovery easier and more 
interactive, the following commands are supported:
+                            <br/><br/>
+                        <table class="table table-bordered">
+                            <thead>
+                            <tr><th>Command</th><th>Description</th></tr>
+                            </thead>
+                            <tbody>
+                            <tr>
+                                <td><strong>DESCRIBE CLUSTER;</strong></td>
+                                <td>Show the current cluster name and its 
partitioner</td>
+                            </tr>
+                            <tr>
+                                <td><strong>DESCRIBE KEYSPACES;</strong></td>
+                                <td>List all existing keyspaces in the cluster 
and their configuration
+                                    (replication factor, durable write 
...)</td>
+                            </tr>
+                            <tr>
+                                <td><strong>DESCRIBE TABLES;</strong></td>
+                                <td>List all existing keyspaces in the cluster 
and for each, all the tables name</td>
+                            </tr>
+                            <tr>
+                                <td><strong>DESCRIBE KEYSPACE &lt;keyspace 
name&gt;;</strong></td>
+                                <td>Describe the given keyspace configuration 
and all its table details (name, columns, ...)</td>
+                            </tr>
+                            <tr>
+                                <td><strong>DESCRIBE TABLE <em>(&lt;keyspace 
name&gt;).</em>&lt;table name&gt;;</strong></td>
+                                <td>
+                                    Describe the given table. If the keyspace 
is not provided, the current
+                                    <strong>logged in</strong> keyspace is 
used. If there is no logged in keyspace,
+                                    the default <em>system</em> keyspace is 
used. If no table is found, an error message is raised
+                                </td>
+                            </tr>
+                            <tr>
+                                <td><strong>DESCRIBE TYPE <em>(&lt;keyspace 
name&gt;).</em>&lt;type name&gt;;</strong></td>
+                                <td>
+                                    Describe the given type(UDT). If the 
keyspace is not provided, the current
+                                    <strong>logged in</strong> keyspace is 
used. If there is no logged in keyspace,
+                                    the default <em>system</em> keyspace is 
used. If no type is found, an error message is raised
+                                </td>
+                            </tr>
+                            </tbody>
+                        </table>
+                        <br/>
+                        <div class="alert alert-danger" role="alert">
+                            Please note that each <strong>DESCRIBE</strong> 
command should be ended by <strong>a semi-colon</strong>.
+                        </div>
+                        </p>
+                        <h3>II Schema Display</h3>
+                        <p>
+                            The schema objects (cluster, keyspace, table &amp; 
type) are displayed in a tabular format.
+                            There is a <strong>drop-down</strong> menu on the 
top left corner to expand objects details.
+                            On the top right menu is shown the Icon legend.
+
+                        </p>
+                    </div>
+                </div>
+
+            </div>
+        </div>
+    </div>
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#881a5e0b-5e52-4474-ba80-787dfe0a770d" aria-expanded="false">
+                    <span class="text-info"><strong>Query 
Parameters</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="881a5e0b-5e52-4474-ba80-787dfe0a770d" class="panel-collapse 
collapse" role="tabpanel">
+            <div class="panel-body">
+
+                <div class="panel panel-default">
+                    <div class="panel-body">
+                        <p>
+                            Sometimes you want to be able to pass runtime 
query parameters to your statements.
+                            Those parameters are <strong>not</strong> part of 
the CQL specs and are specific to the interpreter.
+                            Below is the list of all parameters:
+
+                            <br/><br/>
+                        <table class="table table-bordered">
+                            <caption>
+                                <h4>Query Parameters</h4>
+                            </caption>
+                            <thead>
+                            <tr>
+                                <th>Parameter</th>
+                                <th>Syntax</th>
+                                <th>Description</th>
+                            </tr>
+                            </thead>
+                            <tbody>
+                            <tr>
+                                <td>Consistency Level</td>
+                                
<td><strong>@consistency=<em>value</em></strong></td>
+                                <td>Apply the given consistency level to all 
queries in the paragraph</td>
+                            </tr>
+                            <tr>
+                                <td>Serial Consistency Level</td>
+                                
<td><strong>@serialConsistency=<em>value</em></strong></td>
+                                <td>Apply the given serial consistency level 
to all queries in the paragraph</td>
+                            </tr>
+                            <tr>
+                                <td>Timestamp</td>
+                                <td><strong>@timestamp=<em>long 
value</em></strong></td>
+                                <td>Apply the given timestamp to all queries 
in the paragraph.<br/>
+                                    Please note that timestamp value passed 
directly in CQL statement will override this value
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>Retry Policy</td>
+                                
<td><strong>@retryPolicy=<em>value</em></strong></td>
+                                <td>Apply the given retry policy to all 
queries in the paragraph</td>
+                            </tr>
+                            <tr>
+                                <td>Fetch Size</td>
+                                <td><strong>@fetchSize=<em>int 
value</em></strong></td>
+                                <td>Apply the given fetch size to all queries 
in the paragraph</td>
+                            </tr>
+                            </tbody>
+                        </table>
+                        <br/>
+                        Some parameters only accept restricted values:
+
+                        <br/><br/>
+                        <table class="table table-bordered">
+                            <caption>
+                                <h4>Allowed Values</h4>
+                            </caption>
+                            <thead>
+                            <tr>
+                                <th>Parameter</th>
+                                <th>Possible Values</th>
+                            </tr>
+                            </thead>
+                            <tbody>
+                            <tr>
+                                <td>Consistency Level</td>
+                                <td><strong>ALL, ANY, ONE, TWO, THREE, QUORUM, 
LOCAL_ONE, LOCAL_QUORUM, EACH_QUORUM</strong></td>
+                            </tr>
+                            <tr>
+                                <td>Serial Consistency Level</td>
+                                <td><strong>SERIAL, LOCAL_SERIAL</strong></td>
+                            </tr>
+                            <tr>
+                                <td>Timestamp</td>
+                                <td>Any long value</td>
+                            </tr>
+                            <tr>
+                                <td>Retry Policy</td>
+                                <td>
+                                    <strong>
+                                        DEFAULT, DOWNGRADING_CONSISTENCY, 
FALLTHROUGH, LOGGING_DEFAULT,
+                                        LOGGING_DOWNGRADING, 
LOGGING_FALLTHROUGH
+                                    </strong>
+                                </td>
+                            </tr>
+                            <tr>
+                                <td>Fetch Size</td>
+                                <td>Any integer value</td>
+                            </tr>
+                            </tbody>
+                        </table>
+                        <br/>
+
+                        <div class="alert alert-danger" role="alert">
+                            Please note that you <strong>should not add 
semi-colon (;)</strong> at the end of each parameter statement
+                        </div>
+
+                        Some example:
+                        <br/><br/>
+                        <div class="row">
+                            <div class="col-md-8 col-md-offset-2">
+                                <pre>
+
+    CREATE TABLE IF NOT EXISTS spark_demo.ts(
+        key int PRIMARY KEY,
+        value text
+    );
+    TRUNCATE spark_demo.ts;
+
+    # Timestamp in the past
+    @timestamp=10
+
+    # Force timestamp directly in the first insert
+    INSERT INTO spark_demo.ts(key,value) VALUES(1,'first insert') USING 
TIMESTAMP 100;
+
+    # Select some data to make the clock turn
+    SELECT * FROM spark_demo.albums LIMIT 100;
+
+    # Now insert using the timestamp parameter set at the beginning(10)
+    INSERT INTO spark_demo.ts(key,value) VALUES(1,'second insert');
+
+    # Check for the result. You should see 'first insert'
+    SELECT value FROM spark_demo.ts WHERE key=1;
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+
+                        Some remarks about query parameters:
+                        <br/><br/>
+                        <div class="alert alert-info" role="alert">
+                            <ul>
+                                <li><strong>many</strong> query parameters can 
be set in the same paragraph</li>
+                                <li>if the <strong>same</strong> query 
parameter is set many time with different values,
+                                    the interpreter only take into account the 
first value
+                                </li>
+                                <li>each query parameter applies to 
<strong>all</strong> CQL statement in the same paragraph,
+                                    unless you override the option using plain 
CQL text (like forcing timestamp with the USING clause)
+                                </li>
+                                <li>the order of each query parameter with 
regard to CQL statement does not matter</li>
+                            </ul>
+                        </div>
+                        </p>
+                    </div>
+                </div>
+
+
+            </div>
+        </div>
+    </div>
+
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#2af5a125-8754-40fb-a044-bda10395504f" aria-expanded="false">
+                    <span class="text-info"><strong>Prepared 
Statements</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="2af5a125-8754-40fb-a044-bda10395504f" class="panel-collapse 
collapse" role="tabpanel">
+            <div class="panel-body">
+                <div class="panel panel-default">
+                    <div class="panel-body">
+                        <h3>I Syntax</h3>
+                        <br/>
+                        <p>
+                            For performance reason, it is better to 
<strong>prepare statements</strong> before-hand and reuse
+                            them later by providing bound values. This 
interpreter provides 3 commands to handle prepared and
+                            bound statements:
+                            <br/><br/>
+                        <ol>
+                            <li><strong>@prepare</strong></li>
+                            <li><strong>@bind</strong></li>
+                            <li><strong>@remove_prepared</strong></li>
+                        </ol>
+                        <br/>
+                        Example:
+                        <br/>
+                        <div class="row">
+                            <div class="col-md-10 col-md-offset-1">
+                                <pre>
+
+    @prepare[statement_name]=...
+
+    @bind[statement_name]=’text’, 1223, ’2015-07-30 12:00:01’, null, 
true, [‘list_item1’, ’list_item2’]
+
+    @bind[statement_name_with_no_bound_value]
+
+    @remove_prepare[statement_name]
+
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+
+                        <h3>II @prepare</h3>
+                        <br/>
+                        <p>
+                            You can use the syntax 
"<strong>@prepare[statement_name]=SELECT ...</strong>" to create a prepared 
statement.
+                            The <em>statement_name</em> is mandatory because 
the interpreter prepares the given statement with the
+                            Java driver and saves the generated prepared 
statement in an internal map, using the provided
+                            <em>statement_name</em> as search key.
+                            <br/><br/>
+                        <div class="alert alert-info">
+                            Please note that this internal prepared statement 
map is shared with <strong>all notebooks</strong>
+                            and <strong>all paragraphs</strong> because there 
is only one instance of the interpreter for Cassandra
+                        </div>
+                        <br/>
+                        <div class="alert alert-warning">
+                            If the interpreter encounters many @prepare for 
the <strong>same statement_name</strong> (key),
+                            only the <strong>first</strong> statement will be 
taken into account.
+                        </div>
+                        <br/>
+                        Example:
+                        <br/>
+                        <div class="row">
+                            <div class="col-md-10 col-md-offset-1">
+                                <pre>
+
+    @prepare[select]=SELECT * FROM spark_demo.albums LIMIT ?
+
+    @prepare[select]=SELECT * FROM spark_demo.artists LIMIT ?
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+
+                        For the above example, the prepared statement is 
<strong>"SELECT * FROM spark_demo.albums LIMIT ?"</strong>.
+                        <em>"SELECT * FROM spark_demo.artists LIMIT ?"</em> is 
ignored because an entry already exists in the
+                        prepared statements map with the key 
<strong>select</strong>.
+                        <br/><br/>
+                        In the context of Zeppelin, a notebook can be 
scheduled to be executed at regular interval,
+                        thus it is necessary to avoid re-preparing many time 
the same statement (considered an anti-pattern).
+                        </p>
+                        <h3>III @bind</h3>
+                        <br/>
+                        <p>
+                            Once the statement is prepared (possibly in a 
separated notebook/paragraph). You can bind values to it:
+                            <br/><br/>
+                        <div class="row">
+                            <div class="col-md-10 col-md-offset-1">
+                                <pre>
+
+    @bind[select_first]=10
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+                        Bound values are not mandatory for the 
<strong>@bind</strong> statement.
+                        However if you provide bound values, they need to 
comply to some syntax:
+
+                        <ul>
+                            <li>String values should be enclosed between 
simple quotes ( ‘ )</li>
+                            <li>Date values should be enclosed between simple 
quotes ( ‘ ) and respect the formats:
+                                <ol>
+                                    <li>yyyy-MM-dd HH:MM:ss</li>
+                                    <li>yyyy-MM-dd HH:MM:ss.SSS</li>
+                                </ol>
+                            </li>
+                            <li><strong>null</strong> is parsed as-is</li>
+                            <li><strong>boolean</strong> (true|false) are 
parsed as-is </li>
+                            <li>collection values must follow the
+                                <a 
href="http://docs.datastax.com/en/cql/3.1/cql/cql_using/use_collections_c.html"; 
target="_blank">standard CQL syntax</a>:
+                                <ul>
+                                    <li>list:  [‘list_item1’, 
’list_item2’, ...]</li>
+                                    <li>set: {‘set_item1’, 
‘set_item2’, …}</li>
+                                    <li>map: {‘key1’: ‘val1’, 
‘key2’: ‘val2’, …}</li>
+                                </ul>
+                            </li>
+                            <li>
+                                tuple values should be enclosed between 
parenthesis
+                                (see <a 
href="http://docs.datastax.com/en/cql/3.1/cql/cql_reference/tupleType.html"; 
target="_blank">tuple CQL syntax</a>):
+                                (‘text’, 123, true)
+                            </li>
+                            <li>
+                                udt values should be enclosed between brackets
+                                (see <a 
href="http://docs.datastax.com/en/cql/3.1/cql/cql_using/cqlUseUDT.html"; 
target="_blank">udt CQL syntax</a>):
+                                {stree_name: ‘Beverly Hills’,  number: 
104, zip_code: 90020, state: ‘California’, …}
+                            </li>
+                        </ul>
+                        <br/>
+                        <div class="alert alert-info">
+                            It is possible to use the <strong>@bind</strong> 
statement inside a batch: <br/>
+                            <pre>
+    BEGIN BATCH
+        @bind[insert_user]='jdoe','John DOE'
+        UPDATE users SET age = 27 WHERE login='hsue';
+    APPLY BATCH;
+                            </pre>
+                        </div>
+                        <br/>
+                        </p>
+                        <h3>IV @remove_prepare</h3>
+                        <br/>
+                        <p>
+                            To avoid for a prepared statement to stay forever 
in the prepared statement map, you can use the 
<strong>@remove_prepare[statement_name]</strong> syntax
+                            to remove it. Removing a non-existing prepared 
statement yields no error.
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#4dfe08e1-7ee0-4222-8be0-3d9d43aab38e" aria-expanded="false">
+                    <span class="text-info"><strong>Dynamic 
Forms</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="4dfe08e1-7ee0-4222-8be0-3d9d43aab38e" class="panel-collapse 
collapse" role="tabpanel">
+            <div class="panel-body">
+
+                <div class="panel panel-default">
+                    <div class="panel-body">
+                        <p>
+                            Instead of hard-coding your CQL queries, it is 
possible to use the mustache syntax (<strong>{{ }}</strong>)
+                            to inject simple value or multiple choices forms.
+                            <br/><br/>
+
+                            The syntax for simple parameter is: 
<strong>{{input_Label=default value}}</strong>.
+                            The default value is mandatory because the first 
time the paragraph is executed,
+                            we launch the CQL query before rendering the form 
so at least one value should be provided.
+                            <br/><br/>
+                            The syntax for multiple choices parameter is: 
<strong>{{input_Label=value1 | value2 | … | valueN }}</strong>.
+                            By default the first choice is used for CQL query 
the first time the paragraph is executed.
+                            <br/><br/>
+                            Example:
+                            <br/>
+                        <div class="row">
+                            <div class="col-md-10 col-md-offset-1">
+                                <pre>
+
+    #Secondary index on performer style
+    SELECT name, country, performer
+    FROM spark_demo.performers
+    WHERE name='{{performer=Sheryl Crow|Doof|Fanfarlo|Los Paranoia}}'
+    AND styles CONTAINS '{{style=Rock}}';
+
+                                </pre>
+                            </div>
+                        </div>
+                        <br/>
+
+                        In the above example, the first CQL query will be 
executed for <em>performer='Sheryl Crow'</em>
+                        AND <em>style='Rock'</em>. For subsequent queries, you 
can change the value directly using the form.
+                        Please note that we enclosed the {{ }} block between 
simple quotes (') because Cassandra expects a String here.
+                        We could have also use the 
<strong>{{style='Rock'}}</strong> syntax but this time, the value
+                        displayed on the form is <em>'Rock'</em> and not 
<em>Rock</em>.
+
+                        <br/><br/>
+                        <div class="alert alert-info">
+                            It is also possible to use dynamic forms for 
<strong>prepared statements</strong>: <br/>
+                            <strong>@bind[select]=='{{performer=Sheryl 
Crow|Doof|Fanfarlo|Los Paranoia}}', '{{style=Rock}}'</strong>
+                        </div>
+                        </pre>
+                        </p>
+                    </div>
+                </div>
+
+            </div>
+        </div>
+    </div>
+
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#6485679a-ab5b-406b-8281-37f586459754" aria-expanded="false">
+                    <span class="text-info"><strong>Interpreter 
Configuration</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="6485679a-ab5b-406b-8281-37f586459754" class="panel-collapse 
collapse" role="tabpanel">
+            <div class="panel-body">
+                The <strong>Cassandra</strong> interpreter comes with some 
some configuration values for the Java driver:
+
+                <table class="table table-bordered">
+                    <caption>
+                        <h4>Interpreter Configuration</h4>
+                    </caption>
+                    <thead>
+                    <tr>
+                        <th>Parameter</th>
+                        <th>Default Value</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <tr>
+                        <td>cassandra.cluster</td>
+                        <td><strong>Test Cluster</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.compression.protocol</td>
+                        <td><strong>NONE</strong>, possible values: LZ4, 
SNAPPY</td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.credentials.password</td>
+                        <td><strong>none</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.credentials.username</td>
+                        <td><strong>none</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.hosts</td>
+                        <td><strong>localhost</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.interpreter.parallelism</td>
+                        <td><strong>10</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.keyspace</td>
+                        <td><strong>system</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.load.balancing.policy</td>
+                        <td><strong>DEFAULT</strong>, or a FQCN of a custom 
class</td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.max.schema.agreement.wait.second</td>
+                        <td><strong>10</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.native.port</td>
+                        <td><strong>9042</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.core.connection.per.host.local</td>
+                        <td><strong>Protocol V2 and below: 2, V3 and above: 
1</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.core.connection.per.host.remote</td>
+                        <td><strong>Protocol V2 and below: 1, V3 and above: 
1</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.pooling.heartbeat.interval.seconds</td>
+                        <td><strong>30</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.pooling.idle.timeout.seconds</td>
+                        <td><strong>Test Cluster</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.max.connection.per.host.local</td>
+                        <td><strong>Protocol V2 and below: 8, V3 and above: 
1</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.max.connection.per.host.remote</td>
+                        <td><strong>Protocol V2 and below: 2, V3 and above: 
1</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.max.request.per.connection.local</td>
+                        <td><strong>Protocol V2 and below: 128, V3 and above: 
1024</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.max.request.per.connection.remote</td>
+                        <td><strong>Protocol V2 and below: 128, V3 and above: 
256</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.new.connection.threshold.local</td>
+                        <td><strong>Protocol V2 and below: 100, V3 and above: 
800</strong></td>
+                    </tr>
+                    <tr>
+                        
<td>cassandra.pooling.new.connection.threshold.remote</td>
+                        <td><strong>Protocol V2 and below: 100, V3 and above: 
200</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.pooling.pool.timeout.millisecs</td>
+                        <td><strong>5000</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.protocol.version</td>
+                        <td><strong>3</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.query.default.consistency</td>
+                        <td><strong>ONE</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.query.default.fetchSize</td>
+                        <td><strong>5000</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.query.default.serial.consistency</td>
+                        <td><strong>SERIAL</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.reconnection.policy</td>
+                        <td><strong>DEFAULT</strong>, or a FQCN of a custom 
class</td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.retry.policy</td>
+                        <td><strong>DEFAULT</strong>, or a FQCN of a custom 
class</td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.socket.connection.timeout.millisecs</td>
+                        <td><strong>500</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.socket.read.timeout.millisecs</td>
+                        <td><strong>12000</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.socket.tcp.no_delay</td>
+                        <td><strong>true</strong></td>
+                    </tr>
+                    <tr>
+                        <td>cassandra.speculative.execution.policy</td>
+                        <td><strong>DEFAULT</strong>, or a FQCN of a custom 
class</td>
+                    </tr>
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+
+    <div class="panel panel-default">
+        <div class="panel-heading" role="tab">
+            <h4 class="panel-title">
+                <a role="button" data-toggle="collapse" 
data-target="#2d060cba-7f9a-40de-8cc3-d82586d4321e" aria-expanded="false">
+                    <span 
class="text-info"><strong>Miscellaneous</strong></span>
+                </a>
+            </h4>
+        </div>
+        <div id="2d060cba-7f9a-40de-8cc3-d82586d4321e" class="panel-collapse 
collapse" role="tabpanel">
+            <div class="panel-body">
+                <h3>Execution parallelism</h3>
+                It is possible to execute many paragraphs in parallel. 
However, at the back-end side, we’re still using <strong>synchronous</strong> 
queries. Asynchronous execution is only possible when it is possible to return 
a Future value in the <strong>InterpreterResult</strong>. It may be an 
interesting proposal for the Zeppelin project.
+            </div>
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/resources/scalate/NoResult.html
----------------------------------------------------------------------
diff --git a/cassandra/src/test/resources/scalate/NoResult.html 
b/cassandra/src/test/resources/scalate/NoResult.html
new file mode 100644
index 0000000..e7c2d46
--- /dev/null
+++ b/cassandra/src/test/resources/scalate/NoResult.html
@@ -0,0 +1,6 @@
+<div class="container">
+    <div class="row text-center">
+        <h4>No Result</h4>
+    </div>
+    <br>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/resources/scalate/NoResultWithExecutionInfo.html
----------------------------------------------------------------------
diff --git 
a/cassandra/src/test/resources/scalate/NoResultWithExecutionInfo.html 
b/cassandra/src/test/resources/scalate/NoResultWithExecutionInfo.html
new file mode 100644
index 0000000..c8975c8
--- /dev/null
+++ b/cassandra/src/test/resources/scalate/NoResultWithExecutionInfo.html
@@ -0,0 +1,42 @@
+<div class="container">
+    <div class="row text-center">
+        <h4>No Result</h4>
+    </div>
+    <br/>
+    <div class="row">
+        <div class="col-md-3"></div>
+        <div class="col-md-6 col-offset-md-3 table-responsive table-bordered">
+            <table class="table">
+                <caption><h5>Last query execution info</h5></caption>
+                <thead>
+                <tr>
+                    <th>Info</th>
+                    <th>Value</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td>Statement</td>
+                    <td>CREATE TABLE IF NOT EXISTS no_select(id int PRIMARY 
KEY);</td>
+                </tr>
+                <tr>
+                    <td>Achieved Consistency</td>
+                    <td>N/A</td>
+                </tr>
+                <tr>
+                    <td>Tried Hosts</td>
+                    <td>TRIED_HOSTS</td>
+                </tr>
+                <tr>
+                    <td>Queried Hosts</td>
+                    <td>QUERIED_HOSTS</td>
+                </tr>
+                <tr>
+                    <td>Schema In Agreement</td>
+                    <td>true</td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/scala/org/apache/zeppelin/cassandra/BoundValuesParserTest.scala
----------------------------------------------------------------------
diff --git 
a/cassandra/src/test/scala/org/apache/zeppelin/cassandra/BoundValuesParserTest.scala
 
b/cassandra/src/test/scala/org/apache/zeppelin/cassandra/BoundValuesParserTest.scala
new file mode 100644
index 0000000..de14c88
--- /dev/null
+++ 
b/cassandra/src/test/scala/org/apache/zeppelin/cassandra/BoundValuesParserTest.scala
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zeppelin.cassandra
+
+import org.scalatest.{Matchers, BeforeAndAfterEach, FlatSpec}
+
+class BoundValuesParserTest extends FlatSpec
+with BeforeAndAfterEach
+with Matchers {
+
+  val parser = new BoundValuesParser
+
+  "BoundValuesParser" should "parse quoted string" in {
+    //Given
+    val input = """'a'"""
+
+    //When
+    val parsed1 = parser.parse(parser.quotedString,input)
+    val parsed2 = parser.parse(parser.value,input)
+
+    //Then
+    parsed1.get should be("'a'")
+    parsed2.get should be("'a'")
+  }
+
+  "BoundValuesParser" should "parse integer" in {
+    //Given
+    val input = """00123"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("123")
+  }
+
+  "BoundValuesParser" should "parse decimal number" in {
+    //Given
+    val input1 = """00123.35000"""
+    val input2 = """+123."""
+    val input3 = """.35000"""
+    val input4 = """-.35000"""
+
+    //When
+    val parsed1 = parser.parse(parser.value,input1)
+    val parsed2 = parser.parse(parser.value,input2)
+    val parsed3 = parser.parse(parser.value,input3)
+    val parsed4 = parser.parse(parser.value,input4)
+
+    //Then
+    parsed1.get should be("123.35")
+    parsed2.get should be("123.0")
+    parsed3.get should be("0.35")
+    parsed4.get should be("-0.35")
+  }
+
+  "BoundValuesParser" should "parse list" in {
+    //Given
+    val input = """['a','b','c']"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("['a','b','c']")
+  }
+
+  "BoundValuesParser" should "parse set" in {
+    //Given
+    val input = """{'a',2,3.4}"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("{'a',2,3.4}")
+  }
+
+  "BoundValuesParser" should "parse map" in {
+    //Given
+    val input = """{'key1': 'val', 'key2': 2, 'key3': 3.4}"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("{'key1': 'val', 'key2': 2, 'key3': 3.4}")
+  }
+
+  "BoundValuesParser" should "parse tuple" in {
+    //Given
+    val input = """('a',2,3.4)"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("('a',2,3.4)")
+  }
+
+  "BoundValuesParser" should "parse udt" in {
+    //Given
+    val input = """{col1: 'val1', col2: 2, col3: 3.4}"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("{col1: 'val1', col2: 2, col3: 3.4}")
+  }
+
+  "BoundValuesParser" should "parse date" in {
+    //Given
+    val input = """'2015-07-10 14:56:34'"""
+
+    //When
+    val parsed = parser.parse(parser.value,input)
+
+    //Then
+    parsed.get should be("2015-07-10 14:56:34")
+  }
+
+  "BoundValuesParser" should "parse nested types" in {
+
+    //Given
+    val input = "'jdoe','John','DOE'," +
+      "{street_number: 3, street_name: 'Beverly Hills Bld', zip_code: 90209," +
+      " country: 'USA', extra_info: ['Right on the hills','Next to the post 
box']," +
+      " phone_numbers: {'home': 2016778524, 'office': 2015790847} }," +
+      "('USA', 90209, 'Beverly Hills')"
+
+    //When
+    val parsed = parser.parse(parser.values,input)
+
+    //Then
+    parsed.get should be(List(
+      "'jdoe'",
+      "'John'",
+      "'DOE'",
+      "{street_number: 3, street_name: 'Beverly Hills Bld', zip_code: 90209, 
country: 'USA', extra_info: ['Right on the hills','Next to the post box'], 
phone_numbers: {'home': 2016778524, 'office': 2015790847}}",
+      "('USA',90209,'Beverly Hills')"
+    ))
+  }
+
+  "BoundValuesParser" should "not parse mustaches for zeppelin variables" in {
+    //Given
+    val input = "'jdoe',{{firstname='Jdoe'}}"
+
+    //When
+    val parsed = parser.parse(parser.values,input)
+
+    //Then
+    parsed.get should be(List("'jdoe'","{{firstname='Jdoe'}}"))
+
+  }
+
+  "BoundValuesParser" should "parse zeppelin variable" in {
+    //Given
+    val input = """'{{login=jdoe}}'"""
+
+    //When
+    val parsed = parser.parse(parser.values,input)
+
+    //Then
+    parsed.get should be(List("'{{login=jdoe}}'"))
+  }
+
+  "BoundValuesParser" should "parse null value" in {
+    //Given
+    val input = """'login',null,'LASTNAME'"""
+
+    //When
+    val parsed = parser.parse(parser.values,input)
+
+    //Then
+    parsed.get should be(List("'login'","null","'LASTNAME'"))
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
----------------------------------------------------------------------
diff --git 
a/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
 
b/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
new file mode 100644
index 0000000..b1a8866
--- /dev/null
+++ 
b/cassandra/src/test/scala/org/apache/zeppelin/cassandra/ParagraphParserTest.scala
@@ -0,0 +1,585 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zeppelin.cassandra
+
+import com.datastax.driver.core._
+import org.apache.zeppelin.interpreter.InterpreterException
+import org.scalatest.mock.MockitoSugar
+import org.scalatest.{BeforeAndAfterEach, FlatSpec, Matchers}
+import org.apache.zeppelin.cassandra.ParagraphParser._
+import org.apache.zeppelin.cassandra.TextBlockHierarchy._
+
+class ParagraphParserTest extends FlatSpec
+  with BeforeAndAfterEach
+  with Matchers
+  with MockitoSugar {
+
+  val session: Session = mock[Session]
+  val preparedStatements:collection.mutable.Map[String,PreparedStatement] = 
collection.mutable.Map()
+  val parser: ParagraphParser = new ParagraphParser()
+
+
+  "Parser" should "parse mixed statements" in {
+    val query: String = """
+        SELECT * FROM albums LIMIT 10;
+
+        begin UnLoGgEd BATCH
+        INSERT INTO users(id) VALUES(10);
+        @bind[test]='a',12.34
+        apply Batch;
+
+        SELECT * FROM users LIMIT 10;
+
+        BEGIN BATCH
+        Insert INTO users(id) VALUES(11);
+        INSERT INTO users(id) VALUES(12);
+        APPLY BATCH;
+
+        @bind[toto]='a',12.34
+
+        desc table zeppelin.users;
+        describe keyspace zeppelin;
+      """.stripMargin
+
+    val parsed = parser.parse(parser.queries,query)
+
+    parsed.get should be(List(
+      SimpleStm("SELECT * FROM albums LIMIT 10;"),
+      BatchStm(BatchStatement.Type.UNLOGGED,
+        List(
+          SimpleStm("INSERT INTO users(id) VALUES(10);"),
+          BoundStm("test","'a',12.34")
+        )
+      ),
+      SimpleStm("SELECT * FROM users LIMIT 10;"),
+      BatchStm(BatchStatement.Type.LOGGED,
+        List(
+          SimpleStm("Insert INTO users(id) VALUES(11);"),
+          SimpleStm("INSERT INTO users(id) VALUES(12);")
+        )
+      ),
+      BoundStm("toto","'a',12.34"),
+      DescribeTableCmd(Option("zeppelin"),"users"),
+      DescribeKeyspaceCmd("zeppelin")
+    ))
+  }
+
+  "Parser" should "parse single-line comment" in {
+    val query :CharSequence="""#This is a comment""".stripMargin
+
+    val parsed = parser.parseAll[Comment](parser.singleLineComment, query)
+    parsed.get should be(Comment("This is a comment"))
+  }
+
+
+  "Parser" should "parse multi-line comment" in {
+    val query:String =
+      """/*This is a comment
+        |line1
+        |line2
+        |line3
+        |*/
+      """.stripMargin
+
+    val parsed = parser.parseAll(parser.multiLineComment, query)
+    parsed.get should be(Comment("This is a comment\nline1\nline2\nline3\n"))
+  }
+
+  "Parser" should "parse consistency level" in {
+    val query:String =""" @consistency=ONE""".stripMargin
+    val parsed = parser.parseAll(parser.consistency, query)
+    parsed.get should be(Consistency(ConsistencyLevel.ONE))
+  }
+
+  "Parser" should "fails parsing unknown consistency level" in {
+    val query:String =""" @consistency=TEST""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.consistency, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @consistency. It should 
comply to the pattern ${CONSISTENCY_LEVEL_PATTERN.toString}")
+  }
+
+  "Parser" should "parse serial consistency level" in {
+    val query:String =""" @serialConsistency=LOCAL_SERIAL""".stripMargin
+    val parsed = parser.parseAll(parser.serialConsistency, query)
+    parsed.get should be(SerialConsistency(ConsistencyLevel.LOCAL_SERIAL))
+  }
+
+  "Parser" should "fails parsing unknown serial consistency level" in {
+    val query:String =""" @serialConsistency=TEST""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.serialConsistency, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @serialConsistency. It should 
comply to the pattern ${SERIAL_CONSISTENCY_LEVEL_PATTERN.toString}")
+  }
+
+  "Parser" should "parse timestamp" in {
+    val query:String =""" @timestamp=111""".stripMargin
+    val parsed = parser.parseAll(parser.timestamp, query)
+    parsed.get should be(Timestamp(111L))
+  }
+
+  "Parser" should "fails parsing invalid timestamp" in {
+    val query:String =""" @timestamp=TEST""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.timestamp, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @timestamp. It should comply 
to the pattern ${TIMESTAMP_PATTERN.toString}")
+  }
+
+  "Parser" should "parse retry policy" in {
+    val query:String 
="@retryPolicy="+CassandraInterpreter.DOWNGRADING_CONSISTENCY_RETRY
+    val parsed = parser.parseAll(parser.retryPolicy, query)
+    parsed.get should be(DowngradingRetryPolicy)
+  }
+
+  "Parser" should "fails parsing invalid retry policy" in {
+    val query:String =""" @retryPolicy=TEST""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.retryPolicy, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @retryPolicy. It should 
comply to the pattern ${RETRY_POLICIES_PATTERN.toString}")
+  }
+
+  "Parser" should "parse fetch size" in {
+    val query:String ="@fetchSize=100"
+    val parsed = parser.parseAll(parser.fetchSize, query)
+    parsed.get should be(FetchSize(100))
+  }
+
+  "Parser" should "fails parsing invalid fetch size" in {
+    val query:String =""" @fetchSize=TEST""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.fetchSize, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @fetchSize. It should comply 
to the pattern ${FETCHSIZE_PATTERN.toString}")
+  }
+
+  "Parser" should "parse simple statement" in {
+    //Given
+    val query:String =""" sElecT * FROM users LIMIT ? ;""".stripMargin
+
+    //When
+    val parsed = parser.parseAll(parser.genericStatement, query)
+
+    //Then
+    parsed.get should be(SimpleStm("sElecT * FROM users LIMIT ? ;"))
+  }
+
+  "Parser" should "parse prepare" in {
+    //Given
+    val query:String =""" @prepare[select_users]=SELECT * FROM users LIMIT ? 
""".stripMargin
+
+    //When
+    val parsed = parser.parseAll(parser.prepare, query)
+
+    //Then
+    parsed.get should be(PrepareStm("select_users","SELECT * FROM users LIMIT 
?"))
+  }
+
+  "Parser" should "fails parsing invalid prepared statement" in {
+    val query:String =""" @prepare=SELECT * FROM users LIMIT ?""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.prepare, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @prepare. It should comply to 
the pattern: @prepare[prepared_statement_name]=CQL Statement (without 
semi-colon)")
+  }
+
+  "Parser" should "parse remove prepare" in {
+    //Given
+    val query:String =""" @remove_prepare[select_users  ]""".stripMargin
+
+    //When
+    val parsed = parser.parseAll(parser.removePrepare, query)
+
+    //Then
+    parsed.get should be(RemovePrepareStm("select_users"))
+  }
+
+  "Parser" should "fails parsing invalid remove prepared statement" in {
+    val query:String =""" @remove_prepare[select_users]=SELECT * FROM users 
LIMIT ?""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.removePrepare, query)
+    }
+    ex.getMessage should be(s"Invalid syntax for @remove_prepare. It should 
comply to the pattern: @remove_prepare[prepared_statement_name]")
+  }
+
+  "Parser" should "parse bind" in {
+    //Given
+    val query:String =""" @bind[select_users  ]=10,'toto'""".stripMargin
+
+    //When
+    val parsed = parser.parseAll(parser.bind, query)
+
+    //Then
+    parsed.get should be(BoundStm("select_users","10,'toto'"))
+  }
+
+  "Parser" should "fails parsing invalid bind statement" in {
+    val query:String =""" @bind[select_users]=""".stripMargin
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.bind, query)
+    }
+    ex.getMessage should be("""Invalid syntax for @bind. It should comply to 
the pattern: @bind[prepared_statement_name]=10,'jdoe','John 
DOE',12345,'2015-07-32 12:04:23.234' OR @bind[prepared_statement_name] with no 
bound value. No semi-colon""")
+  }
+
+  "Parser" should "parse batch" in {
+    //Given
+    val query:String ="""
+      bEgin Batch
+        Insert INTO users(id) VALUES(10);
+        @bind[select_users  ]=10,'toto'
+        update users SET name ='John DOE' WHERE id=10;
+        dElEtE users WHERE id=11;
+      APPLY BATCH;""".stripMargin
+
+    //When
+    val parsed = parser.parseAll(parser.batch, query)
+
+    //Then
+    parsed.get should be(
+      BatchStm(
+        BatchStatement.Type.LOGGED,
+        List[QueryStatement](
+          SimpleStm("Insert INTO users(id) VALUES(10);"),
+          BoundStm("select_users", "10,'toto'"),
+          SimpleStm("update users SET name ='John DOE' WHERE id=10;"),
+          SimpleStm("dElEtE users WHERE id=11;")
+        )
+      )
+    )
+  }
+
+  "Parser" should "fails parsing invalid batch type" in {
+    val query:String ="""BEGIN UNKNOWN BATCH""".stripMargin
+
+    val ex = intercept[InterpreterException] {
+      parser.extractBatchType(query)
+    }
+    ex.getMessage should be(s"""Invalid syntax for BEGIN BATCH. It should 
comply to the pattern: ${BATCH_PATTERN.toString}""")
+  }
+
+  "Parser" should "parse query parameter with statement" in {
+
+      val query:String = "@serialConsistency=SERIAL\n" +
+        "SELECT * FROM zeppelin.artists LIMIT 1;"
+
+      val parsed = parser.parseAll(parser.queries, query)
+
+      parsed.get should be (List(
+          SerialConsistency(ConsistencyLevel.SERIAL),
+          SimpleStm("SELECT * FROM zeppelin.artists LIMIT 1;")
+      ))
+  }
+
+  "Parser" should "parse multi-line single statement" in {
+
+    val query:String = "CREATE TABLE IF NOT EXISTS zeppelin.albums(\n" +
+      "    title text PRIMARY KEY,\n" +
+      "    artist text,\n" +
+      "    year int\n" +
+      ");\n";
+
+    val parsed = parser.parseAll(parser.queries, query)
+
+    parsed.get should be (List(
+      SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n    title text 
PRIMARY KEY,\n    artist text,\n    year int\n);")
+    ))
+  }
+
+  "Parser" should "parse multi-line statements" in {
+    val query:String = "CREATE TABLE IF NOT EXISTS zeppelin.albums(\n" +
+      "    title text PRIMARY KEY,\n" +
+      "    artist text,\n" +
+      "    year int\n" +
+      ");\n" +
+      "@consistency=THREE\n" +
+      "@serialConsistency=SERIAL\n" +
+      "BEGIN BATCH\n"+
+      "   INSERT INTO zeppelin.albums(title,artist,year) VALUES('The 
Impossible Dream EP','Carter the Unstoppable Sex Machine',1992);"+
+      "   INSERT INTO zeppelin.albums(title,artist,year) VALUES('The Way You 
Are','Tears for Fears',1983);"+
+      "   INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('Primitive','Soulfly',2003);\n"+
+      "APPLY BATCH;\n"+
+      "@timestamp=10\n" +
+      "@retryPolicy=DOWNGRADING_CONSISTENCY\n" +
+      "SELECT * FROM zeppelin.albums;";
+
+    val parsed = parser.parseAll(parser.queries, query)
+
+    parsed.get should be (List(
+      SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n    title text 
PRIMARY KEY,\n    artist text,\n    year int\n);"),
+      Consistency(ConsistencyLevel.THREE),
+      SerialConsistency(ConsistencyLevel.SERIAL),
+      BatchStm(BatchStatement.Type.LOGGED,
+        List(
+          SimpleStm("INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('The Impossible Dream EP','Carter the Unstoppable Sex Machine',1992);"),
+          SimpleStm("INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('The Way You Are','Tears for Fears',1983);"),
+          SimpleStm("INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('Primitive','Soulfly',2003);")
+        )
+      ),
+      Timestamp(10L),
+      DowngradingRetryPolicy,
+      SimpleStm("SELECT * FROM zeppelin.albums;")
+    ))
+  }
+
+  "Parser" should "parse mixed single-line and multi-line statements" in {
+
+    val query:String = "CREATE TABLE IF NOT EXISTS zeppelin.albums(\n" +
+      "    title text PRIMARY KEY,\n" +
+      "    artist text,\n" +
+      "    year int\n" +
+      ");\n" +
+      "BEGIN BATCH"+
+      "   INSERT INTO zeppelin.albums(title,artist,year) VALUES('The 
Impossible Dream EP','Carter the Unstoppable Sex Machine',1992);"+
+      "   INSERT INTO zeppelin.albums(title,artist,year) VALUES('The Way You 
Are','Tears for Fears',1983);"+
+      "   INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('Primitive','Soulfly',2003);\n"+
+      "APPLY BATCH;"+
+      "SELECT * FROM zeppelin.albums;";
+
+    val parsed = parser.parseAll(parser.queries, query)
+
+    parsed.get should be (List(
+      SimpleStm("CREATE TABLE IF NOT EXISTS zeppelin.albums(\n    title text 
PRIMARY KEY,\n    artist text,\n    year int\n);"),
+      BatchStm(BatchStatement.Type.LOGGED,
+        List(
+          SimpleStm("INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('The Impossible Dream EP','Carter the Unstoppable Sex Machine',1992);"),
+          SimpleStm("INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('The Way You Are','Tears for Fears',1983);"),
+          SimpleStm("INSERT INTO zeppelin.albums(title,artist,year) 
VALUES('Primitive','Soulfly',2003);")
+        )
+      ),
+      SimpleStm("SELECT * FROM zeppelin.albums;")
+    ))
+  }
+
+  "Parser" should "parse a block queries with comments" in {
+    val query =
+      """
+        /*
+         This example show how to force a
+         timestamp on the query
+        */
+        #Timestamp in the past
+        @timestamp=10
+        CREATE TABLE IF NOT EXISTS spark_demo.ts(key int PRIMARY KEY, value 
text);
+
+        TRUNCATE spark_demo.ts;
+
+        #Force timestamp directly in the first INSERT
+        INSERT INTO spark_demo.ts(key,value) VALUES(1,'val1') USING TIMESTAMP 
100;
+
+        #Select some data to loose some time
+        SELECT * FROM spark_demo.albums LIMIT 100;
+
+        #Use @timestamp value set at the beginning(10)
+        INSERT INTO spark_demo.ts(key,value) VALUES(1,'val2');
+
+        #Check the result
+        SELECT * FROM spark_demo.ts WHERE key=1;
+
+      """.stripMargin
+
+    val parsed = parser.parseAll(parser.queries, query)
+
+    parsed.get should be (List(
+        Comment("\n         This example show how to force a\n         
timestamp on the query\n        "),
+        Comment("Timestamp in the past"),
+        Timestamp(10L),
+        SimpleStm("CREATE TABLE IF NOT EXISTS spark_demo.ts(key int PRIMARY 
KEY, value text);"),
+        SimpleStm("TRUNCATE spark_demo.ts;"),
+        Comment("Force timestamp directly in the first INSERT"),
+        SimpleStm("INSERT INTO spark_demo.ts(key,value) VALUES(1,'val1') USING 
TIMESTAMP 100;"),
+        Comment("Select some data to loose some time"),
+        SimpleStm("SELECT * FROM spark_demo.albums LIMIT 100;"),
+        Comment("Use @timestamp value set at the beginning(10)"),
+        SimpleStm("INSERT INTO spark_demo.ts(key,value) VALUES(1,'val2');"),
+        Comment("Check the result"),
+        SimpleStm("SELECT * FROM spark_demo.ts WHERE key=1;")
+      )
+    )
+  }
+
+  "Parser" should "remove prepared statement" in {
+    val queries =
+      """
+        #Removing an unknown statement should has no side effect
+        @remove_prepare[unknown_statement]
+        @remove_prepare[select_artist_by_name]
+
+        #This should fail because the 'select_artist_by_name' has been removed
+        @bind[select_artist_by_name]='The Beatles'
+      """.stripMargin
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(
+      Comment("Removing an unknown statement should has no side effect"),
+      RemovePrepareStm("unknown_statement"),
+      RemovePrepareStm("select_artist_by_name"),
+      Comment("This should fail because the 'select_artist_by_name' has been 
removed"),
+      BoundStm("select_artist_by_name","'The Beatles'")
+    ))
+  }
+
+  "Parser" should "parse only parameter" in {
+    val queries =
+      "@fetchSize=1000"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(FetchSize(1000)))
+  }
+
+
+  "Parser" should "parse describe cluster" in {
+    val queries ="Describe ClUsTeR;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get(0) shouldBe a [DescribeClusterCmd]
+  }
+
+  "Parser" should "fail parsing describe cluster" in {
+    val queries ="Describe ClUsTeR"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for DESCRIBE CLUSTER. It should 
comply to the pattern: ${DESCRIBE_CLUSTER_PATTERN.toString}")
+  }
+
+  "Parser" should "parse describe keyspaces" in {
+    val queries ="Describe KeYsPaCeS;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get(0) shouldBe a [DescribeKeyspacesCmd]
+  }
+
+  "Parser" should "fail parsing describe keyspaces" in {
+    val queries ="Describe KeYsPaCeS"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for DESCRIBE KEYSPACES. It should 
comply to the pattern: ${DESCRIBE_KEYSPACES_PATTERN.toString}")
+  }
+
+  "Parser" should "parse describe tables" in {
+    val queries ="Describe TaBlEs;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get(0) shouldBe a [DescribeTablesCmd]
+  }
+
+  "Parser" should "fail parsing describe tables" in {
+    val queries ="Describe TaBlEs"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for DESCRIBE TABLES. It should 
comply to the pattern: ${DESCRIBE_TABLES_PATTERN.toString}")
+  }
+
+  "Parser" should "parse describe keyspace" in {
+    val queries ="Describe KeYsPaCe toto;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(DescribeKeyspaceCmd("toto")))
+  }
+
+  "Parser" should "fail parsing describe keyspace" in {
+    val queries ="Describe KeYsPaCe toto"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for DESCRIBE KEYSPACE. It should 
comply to the pattern: ${DESCRIBE_KEYSPACE_PATTERN.toString}")
+  }
+
+  "Parser" should "parse describe table" in {
+    val queries ="Describe TaBlE toto;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(DescribeTableCmd(None,"toto")))
+  }
+
+  "Parser" should "parse describe table with keyspace" in {
+    val queries ="Describe TaBlE ks.toto;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(DescribeTableCmd(Some("ks"),"toto")))
+  }
+
+  "Parser" should "fail parsing describe table" in {
+    val queries ="Describe TaBlE toto"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for DESCRIBE TABLE. It should 
comply to the patterns: " +
+      s"${DESCRIBE_TABLE_WITH_KEYSPACE_PATTERN.toString} or 
${DESCRIBE_TABLE_PATTERN.toString}")
+  }
+
+  "Parser" should "parse describe type" in {
+    val queries ="Describe Type toto;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(DescribeUDTCmd(None,"toto")))
+  }
+
+  "Parser" should "parse describe type with keyspace" in {
+    val queries ="Describe Type ks.toto;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get should be(List(DescribeUDTCmd(Some("ks"),"toto")))
+  }
+
+  "Parser" should "fail parsing describe type" in {
+    val queries ="Describe Type toto"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for DESCRIBE TYPE. It should 
comply to the patterns: " +
+      s"${DESCRIBE_TYPE_WITH_KEYSPACE_PATTERN.toString} or 
${DESCRIBE_TYPE_PATTERN.toString}")
+  }
+
+  "Parser" should "parse help" in {
+    val queries ="hElp;"
+
+    val parsed = parser.parseAll(parser.queries, queries)
+
+    parsed.get(0) shouldBe a [HelpCmd]
+  }
+
+  "Parser" should "fail parsing help" in {
+    val queries ="HELP"
+
+    val ex = intercept[InterpreterException] {
+      parser.parseAll(parser.queries, queries)
+    }
+    ex.getMessage should be(s"Invalid syntax for HELP. It should comply to the 
patterns: " +
+      s"${HELP_PATTERN.toString}")
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/conf/zeppelin-site.xml.template
----------------------------------------------------------------------
diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index c2294cb..8d0a7f1 100644
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -87,7 +87,7 @@
 
 <property>
   <name>zeppelin.interpreters</name>
-  
<value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter</value>
+  
<value>org.apache.zeppelin.spark.SparkInterpreter,org.apache.zeppelin.spark.PySparkInterpreter,org.apache.zeppelin.spark.SparkSqlInterpreter,org.apache.zeppelin.spark.DepInterpreter,org.apache.zeppelin.markdown.Markdown,org.apache.zeppelin.angular.AngularInterpreter,org.apache.zeppelin.shell.ShellInterpreter,org.apache.zeppelin.hive.HiveInterpreter,org.apache.zeppelin.tajo.TajoInterpreter,org.apache.zeppelin.flink.FlinkInterpreter,org.apache.zeppelin.lens.LensInterpreter,org.apache.zeppelin.ignite.IgniteInterpreter,org.apache.zeppelin.ignite.IgniteSqlInterpreter,org.apache.zeppelin.cassandra.CassandraInterpreter</value>
   <description>Comma separated interpreter configurations. First interpreter 
become a default</description>
 </property>
 

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index a484405..9e5f54e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -95,6 +95,7 @@
     <module>flink</module>
     <module>ignite</module>
     <module>lens</module>
+    <module>cassandra</module>
     <module>zeppelin-web</module>
     <module>zeppelin-server</module>
     <module>zeppelin-distribution</module>

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/b9583c6e/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
index d5c8155..086c15e 100644
--- 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
+++ 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/conf/ZeppelinConfiguration.java
@@ -415,7 +415,8 @@ public class ZeppelinConfiguration extends XMLConfiguration 
{
         + "org.apache.zeppelin.flink.FlinkInterpreter,"
         + "org.apache.zeppelin.ignite.IgniteInterpreter,"
         + "org.apache.zeppelin.ignite.IgniteSqlInterpreter,"
-        + "org.apache.zeppelin.lens.LensInterpreter"),
+        + "org.apache.zeppelin.lens.LensInterpreter,"
+        + "org.apache.zeppelin.cassandra.CassandraInterpreter"),
     ZEPPELIN_INTERPRETER_DIR("zeppelin.interpreter.dir", "interpreter"),
     
ZEPPELIN_INTERPRETER_CONNECT_TIMEOUT("zeppelin.interpreter.connect.timeout", 
30000),
     ZEPPELIN_ENCODING("zeppelin.encoding", "UTF-8"),


Reply via email to