You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jh...@apache.org on 2015/05/29 13:48:35 UTC

svn commit: r1682430 [6/9] - in /incubator/calcite/site: ./ css/ develop/ docs/ downloads/ fonts/ help/ img/ js/ news/ news/2015/ news/2015/01/ news/2015/01/31/ news/2015/01/31/release-1.0.0-incubating/ news/2015/03/ news/2015/03/13/ news/2015/03/13/re...

Added: incubator/calcite/site/docs/stream.html
URL: http://svn.apache.org/viewvc/incubator/calcite/site/docs/stream.html?rev=1682430&view=auto
==============================================================================
--- incubator/calcite/site/docs/stream.html (added)
+++ incubator/calcite/site/docs/stream.html Fri May 29 11:48:34 2015
@@ -0,0 +1,1738 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <title>Streaming</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <meta name="generator" content="Jekyll v2.4.0">
+  <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic,900">
+  <link rel="stylesheet" href="/css/screen.css">
+  <link rel="icon" type="image/x-icon" href="/favicon.ico">
+  <!--[if lt IE 9]>
+  <script src="/js/html5shiv.min.js"></script>
+  <script src="/js/respond.min.js"></script>
+  <![endif]-->
+</head>
+
+
+<body class="wrap">
+  <header role="banner">
+  <nav class="mobile-nav show-on-mobiles">
+    <ul>
+  <li class="">
+    <a href="/">Home</a>
+  </li>
+  <li class="current">
+    <a href="/docs/">Documentation</a>
+  </li>
+  <li class="">
+    <a href="/talks/">Talks</a>
+  </li>
+  <li class="">
+    <a href="/news/">News</a>
+  </li>
+  <li class="">
+    <a href="/help/">Help</a>
+  </li>
+  <li class="">
+    <a href="/develop/">Develop</a>
+  </li>
+</ul>
+
+  </nav>
+  <div class="grid">
+    <div class="unit one-third center-on-mobiles">
+      <h1>
+        <a href="/">
+          <span class="sr-only">Apache Calcite</span>
+          <img src="/img/logo.png" width="226" height="140" alt="Calcite Logo">
+        </a>
+      </h1>
+    </div>
+    <nav class="main-nav unit two-thirds hide-on-mobiles">
+      <ul>
+  <li class="">
+    <a href="/">Home</a>
+  </li>
+  <li class="current">
+    <a href="/docs/">Documentation</a>
+  </li>
+  <li class="">
+    <a href="/talks/">Talks</a>
+  </li>
+  <li class="">
+    <a href="/news/">News</a>
+  </li>
+  <li class="">
+    <a href="/help/">Help</a>
+  </li>
+  <li class="">
+    <a href="/develop/">Develop</a>
+  </li>
+</ul>
+
+    </nav>
+  </div>
+</header>
+
+
+    <section class="docs">
+    <div class="grid">
+
+      <div class="docs-nav-mobile unit whole show-on-mobiles">
+  <select onchange="if (this.value) window.location.href=this.value">
+    <option value="">Navigate the docs…</option>
+    
+    <optgroup label="Overview">
+      
+
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/index.html">Background</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/tutorial.html">Tutorial</option>
+    
+  
+
+  
+
+  
+    
+  
+    
+      <option value="/docs/algebra.html">Algebra</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+    <optgroup label="Advanced">
+      
+
+
+  
+
+  
+    
+      <option value="/docs/adapter.html">Adapters</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/avatica.html">Avatica</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/stream.html">Streaming</option>
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/lattice.html">Lattices</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+    <optgroup label="Reference">
+      
+
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/reference.html">SQL language</option>
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/model.html">JSON models</option>
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/howto.html">HOWTO</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+    <optgroup label="Meta">
+      
+
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/downloads.html">Downloads</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/history.html">History</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/contributing.html">Contributing</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+      <option value="/docs/api.html">API</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+  </select>
+</div>
+
+
+      <div class="unit four-fifths">
+        <article>
+          <h1>Streaming</h1>
+          <!--
+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.
+-->
+
+<p>Calcite has extended SQL and relational algebra in order to support
+streaming queries.</p>
+
+<p>Streams are collections to records that flow continuously, and forever.
+Unlike tables, they are not typically stored on disk, but flow over the
+network and are held for short periods of time in memory.</p>
+
+<p>Streams complement tables because they represent what is happening in the
+present and future of the enterprise whereas tables represent the past.
+It is very common for a stream to be archived into a table.</p>
+
+<p>Like tables, you often want to query streams in a high-level language
+based on relational algebra, validated according to a schema, and optimized
+to take advantage of available resources and algorithms.</p>
+
+<p>Calcite’s SQL is an extension to standard SQL, not another ‘SQL-like’ language.
+The distinction is important, for several reasons:
+* Streaming SQL is easy to learn for anyone who knows regular SQL.
+* The semantics are clear, because we aim to produce the same results on a
+  stream as if the same data were in a table.
+* You can write queries that combine streams and tables (or the history of
+  a stream, which is basically an in-memory table).
+* Lots of existing tools can generate standard SQL.</p>
+
+<p>If you don’t use the <code>STREAM</code> keyword, you are back in regular
+standard SQL.</p>
+
+<h2 id="an-example-schema">An example schema</h2>
+
+<p>Our streaming SQL examples use the following schema:
+* <code>Orders (rowtime, productId, orderId, units)</code> - a stream and a table
+* <code>Products (rowtime, productId, name)</code> - a table
+* <code>Shipments (rowtime, orderId)</code> - a stream</p>
+
+<h2 id="a-simple-query">A simple query</h2>
+
+<p>Let’s start with the simplest streaming query:</p>
+
+<p>```sql
+SELECT STREAM *
+FROM Orders;</p>
+
+<p>rowtime | productId | orderId | units
+———-+———–+———+——-
+ 10:17:00 |        30 |       5 |     4
+ 10:17:05 |        10 |       6 |     1
+ 10:18:05 |        20 |       7 |     2
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:04:00 |        10 |      10 |     1
+ 11:09:30 |        40 |      11 |    12
+ 11:24:11 |        10 |      12 |     4
+```</p>
+
+<p>This query reads all columns and rows from the <code>Orders</code> stream.
+Like any streaming query, it never terminates. It outputs a record whenever
+a record arrives in <code>Orders</code>.</p>
+
+<p>Type <code>Control-C</code> to terminate the query.</p>
+
+<p>The <code>STREAM</code> keyword is the main extension in streaming SQL. It tells the
+system that you are interested in incoming orders, not existing ones. The query</p>
+
+<p>```sql
+SELECT *
+FROM Orders;</p>
+
+<p>rowtime | productId | orderId | units
+———-+———–+———+——-
+ 08:30:00 |        10 |       1 |     3
+ 08:45:10 |        20 |       2 |     1
+ 09:12:21 |        10 |       3 |    10
+ 09:27:44 |        30 |       4 |     2</p>
+
+<p>4 records returned.
+```</p>
+
+<p>is also valid, but will print out all existing orders and then terminate. We
+call it a <em>relational</em> query, as opposed to <em>streaming</em>. It has traditional
+SQL semantics.</p>
+
+<p><code>Orders</code> is special, in that it has both a stream and a table. If you try to run
+a streaming query on a table, or a relational query on a stream, Calcite gives
+an error:</p>
+
+<p>```sql
+&gt; SELECT * FROM Shipments;
+ERROR: Cannot convert stream ‘SHIPMENTS’ to a table</p>
+
+<blockquote>
+  <p>SELECT STREAM * FROM Products;
+ERROR: Cannot convert table ‘PRODUCTS’ to a stream
+```</p>
+</blockquote>
+
+<h1 id="filtering-rows">Filtering rows</h1>
+
+<p>Just as in regular SQL, you use a <code>WHERE</code> clause to filter rows:</p>
+
+<p>```sql
+SELECT STREAM *
+FROM Orders
+WHERE units &gt; 3;</p>
+
+<p>rowtime | productId | orderId | units
+———-+———–+———+——-
+ 10:17:00 |        30 |       5 |     4
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:09:30 |        40 |      11 |    12
+ 11:24:11 |        10 |      12 |     4
+```</p>
+
+<h1 id="projecting-expressions">Projecting expressions</h1>
+
+<p>Use expressions in the <code>SELECT</code> clause to choose which columns to return or
+compute expressions:</p>
+
+<p>```sql
+SELECT STREAM rowtime,
+  ‘An order for ‘ || units || ‘ ‘
+    || CASE units WHEN 1 THEN ‘unit’ ELSE ‘units’ END
+    || ‘ of product #’ || productId AS description
+FROM Orders;</p>
+
+<p>rowtime | description
+———-+—————————————
+ 10:17:00 | An order for 4 units of product #30
+ 10:17:05 | An order for 1 unit of product #10
+ 10:18:05 | An order for 2 units of product #20
+ 10:18:07 | An order for 20 units of product #30
+ 11:02:00 | An order by 6 units of product #10
+ 11:04:00 | An order by 1 unit of product #10
+ 11:09:30 | An order for 12 units of product #40
+ 11:24:11 | An order by 4 units of product #10
+```</p>
+
+<p>We recommend that you always include the <code>rowtime</code> column in the <code>SELECT</code>
+clause. Having a sorted timestamp in each stream and streaming query makes it
+possible to do advanced calculations later, such as <code>GROUP BY</code> and <code>JOIN</code>.</p>
+
+<h1 id="tumbling-windows">Tumbling windows</h1>
+
+<p>There are several ways to compute aggregate functions on streams. The
+differences are:
+* How many rows come out for each row in?
+* Does each incoming value appear in one total, or more?
+* What defines the “window”, the set of rows that contribute to a given output row?
+* Is the result a stream or a relation?</p>
+
+<p>First we’ll look a <em>tumbling window</em>, which is defined by a streaming
+<code>GROUP BY</code>. Here is an example:</p>
+
+<p>```sql
+SELECT STREAM FLOOR(rowtime TO HOUR) AS rowtime,
+  productId,
+  COUNT(*) AS c,
+  SUM(units) AS units
+FROM Orders
+GROUP BY FLOOR(rowtime TO HOUR), productId;</p>
+
+<p>rowtime | productId |       c | units
+———-+———–+———+——-
+ 10:00:00 |        30 |       2 |    24
+ 10:00:00 |        10 |       1 |     1
+ 10:00:00 |        20 |       1 |     7
+ 11:00:00 |        10 |       3 |    11
+ 11:00:00 |        40 |       1 |    12
+```</p>
+
+<p>The result is a stream. At 11 o’clock, Calcite emits a sub-total for every
+<code>productId</code> that had an order since 10 o’clock. At 12 o’clock, it will emit
+the orders that occurred between 11:00 and 12:00. Each input row contributes to
+only one output row.</p>
+
+<p>How did Calcite know that the 10:00:00 sub-totals were complete at 11:00:00,
+so that it could emit them? It knows that <code>rowtime</code> is increasing, and it knows
+that <code>FLOOR(rowtime TO HOUR)</code> is also increasing. So, once it has seen a row
+at or after 11:00:00, it will never see a row that will contribute to a 10:00:00
+total.</p>
+
+<p>A column or expression that is increasing or decreasing is said to be
+<em>monotonic</em>. Without a monotonic expression in the <code>GROUP BY</code> clause, Calcite is
+not able to make progress, and it will not allow the query:</p>
+
+<p><code>sql
+&gt; SELECT STREAM productId,
+&gt;   COUNT(*) AS c,
+&gt;   SUM(units) AS units
+&gt; FROM Orders
+&gt; GROUP BY productId;
+ERROR: Streaming aggregation requires at least one monotonic expression in GROUP BY clause
+</code></p>
+
+<p>Monotonic columns need to be declared in the schema. The monotonicity is
+enforced when records enter the stream and assumed by queries that read from
+that stream. We recommend that you give each stream a timestamp column called
+<code>rowtime</code>, but you can declare others, <code>orderId</code>, for example.</p>
+
+<h1 id="filtering-after-aggregation">Filtering after aggregation</h1>
+
+<p>As in standard SQL, you can apply a <code>HAVING</code> clause to filter rows emitted by
+a streaming <code>GROUP BY</code>:</p>
+
+<p>```sql
+SELECT STREAM FLOOR(rowtime TO HOUR) AS rowtime,
+  productId
+FROM Orders
+GROUP BY FLOOR(rowtime TO HOUR), productId
+HAVING COUNT(*) &gt; 2 OR SUM(units) &gt; 10;</p>
+
+<p>rowtime | productId
+———-+———–
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+```</p>
+
+<h1 id="sub-queries-views-and-sqls-closure-property">Sub-queries, views and SQL’s closure property</h1>
+
+<p>The previous <code>HAVING</code> query can be expressed using a <code>WHERE</code> clause on a
+sub-query:</p>
+
+<p>```sql
+SELECT STREAM rowtime, productId
+FROM (
+  SELECT FLOOR(rowtime TO HOUR) AS rowtime,
+    productId,
+    COUNT(*) AS c,
+    SUM(units) AS su
+  FROM Orders
+  GROUP BY FLOOR(rowtime TO HOUR), productId)
+WHERE c &gt; 2 OR su &gt; 10;</p>
+
+<p>rowtime | productId
+———-+———–
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+```</p>
+
+<p><code>HAVING</code> was introduced in the early days of SQL, when a way was needed to
+perform a filter <em>after</em> aggregation. (Recall that <code>WHERE</code> filters rows before
+they enter the <code>GROUP BY</code> clause.)</p>
+
+<p>Since then, SQL has become a mathematically closed language, which means that
+any operation you can perform on a table can also perform on a query.</p>
+
+<p>The <em>closure property</em> of SQL is extremely powerful. Not only does it render
+<code>HAVING</code> obsolete (or, at least, reduce it to syntactic sugar), it makes views
+possible:</p>
+
+<p>```sql
+CREATE VIEW HourlyOrderTotals (rowtime, productId, c, su) AS
+  SELECT FLOOR(rowtime TO HOUR),
+    productId,
+    COUNT(*),
+    SUM(units)
+  FROM Orders
+  GROUP BY FLOOR(rowtime TO HOUR), productId;</p>
+
+<p>SELECT STREAM rowtime, productId
+FROM HourlyOrderTotals
+WHERE c &gt; 2 OR su &gt; 10;</p>
+
+<p>rowtime | productId
+———-+———–
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+```</p>
+
+<p>Sub-queries in the <code>FROM</code> clause are sometimes referred to as “inline views”,
+but really, nested queries are more fundamental. Views are just a convenient
+way to carve your SQL into manageable chunks.</p>
+
+<p>Many people find that nested queries and views are even more useful on streams
+than they are on relations. Streaming queries are pipelines of
+operators all running continuously, and often those pipelines get quite long.
+Nested queries and views help to express and manage those pipelines.</p>
+
+<p>And, by the way, a <code>WITH</code> clause can accomplish the same as a sub-query or
+a view:</p>
+
+<p>```sql
+WITH HourlyOrderTotals (rowtime, productId, c, su) AS (
+  SELECT FLOOR(rowtime TO HOUR),
+    productId,
+    COUNT(*),
+    SUM(units)
+  FROM Orders
+  GROUP BY FLOOR(rowtime TO HOUR), productId)
+SELECT STREAM rowtime, productId
+FROM HourlyOrderTotals
+WHERE c &gt; 2 OR su &gt; 10;</p>
+
+<p>rowtime | productId
+———-+———–
+ 10:00:00 |        30
+ 11:00:00 |        10
+ 11:00:00 |        40
+```</p>
+
+<h2 id="converting-between-streams-and-relations">Converting between streams and relations</h2>
+
+<p>Look back at the definition of the <code>HourlyOrderTotals</code> view.
+Is the view a stream or a relation?</p>
+
+<p>It does not contain the <code>STREAM</code> keyword, so it is a relation.
+However, it is a relation that can be converted into a stream.</p>
+
+<p>You can use it in both relational and streaming queries:</p>
+
+<p>```sql
+# A relation; will query the historic Orders table.
+# Returns the largest number of product #10 ever sold in one hour.
+SELECT max(su)
+FROM HourlyOrderTotals
+WHERE productId = 10;</p>
+
+<h1 id="a-stream-will-query-the-orders-stream">A stream; will query the Orders stream.</h1>
+<p># Returns every hour in which at least one product #10 was sold.
+SELECT STREAM rowtime
+FROM HourlyOrderTotals
+WHERE productId = 10;
+```</p>
+
+<p>This approach is not limited to views and sub-queries.
+Following the approach set out in CQL [<a href="#ref1">1</a>], every query
+in streaming SQL is defined as a relational query and converted to a stream
+using the <code>STREAM</code> keyword in the top-most <code>SELECT</code>.</p>
+
+<p>If the <code>STREAM</code> keyword is present in sub-queries or view definitions, it has no
+effect.</p>
+
+<p>At query preparation time, Calcite figures out whether the relations referenced
+in the query can be converted to streams or historical relations.</p>
+
+<p>Sometimes a stream makes available some of its history (say the last 24 hours of
+data in an Apache Kafka [<a href="#ref2">2</a>] topic)
+but not all. At run time, Calcite figures out whether there is sufficient
+history to run the query, and if not, gives an error.</p>
+
+<h2 id="hopping-windows">Hopping windows</h2>
+
+<p>Previously we saw how to define a tumbling window using a <code>GROUP BY</code> clause.
+Each record contributed to a single sub-total record, the one containing its
+hour and product id.</p>
+
+<p>But suppose we want to emit, every hour, the number of each product ordered over
+the past three hours. To do this, we use <code>SELECT ... OVER</code> and a sliding window
+to combine multiple tumbling windows.</p>
+
+<p><code>sql
+SELECT STREAM rowtime,
+  productId,
+  SUM(su) OVER w AS su,
+  SUM(c) OVER w AS c
+FROM HourlyTotals
+WINDOW w AS (
+  ORDER BY rowtime
+  PARTITION BY productId
+  RANGE INTERVAL '2' HOUR PRECEDING)
+</code></p>
+
+<p>This query uses the <code>HourlyOrderTotals</code> view defined previously.
+The 2 hour interval combines the totals timestamped 09:00:00, 10:00:00 and
+11:00:00 for a particular product into a single total timestamped 11:00:00 and
+summarizing orders for that product between 09:00:00 and 12:00:00.</p>
+
+<h2 id="limitations-of-tumbling-and-hopping-windows">Limitations of tumbling and hopping windows</h2>
+
+<p>In the present syntax, we acknowledge that it is not easy to create certain
+kinds of windows.</p>
+
+<p>First, let’s consider tumbling windows over complex periods.</p>
+
+<p>The <code>FLOOR</code> and <code>CEIL</code> functions make is easy to create a tumbling window that
+emits on a whole time unit (say every hour, or every minute) but less easy to
+emit, say, every 15 minutes. One could imagine an extension to the <code>FLOOR</code>
+function that emits unique values on just about any periodic basis (say in 11
+minute intervals starting from midnight of the current day).</p>
+
+<p>Next, let’s consider hopping windows whose retention period is not a multiple
+of its emission period. Say we want to output, at the top of each hour, the
+orders for the previous 7,007 seconds. If we were to simulate this hopping
+window using a sliding window over a tumbling window, as before, we would have
+to sum lots of 1-second windows (because 3,600 and 7,007 are co-prime).
+This is a lot of effort for both the system and the person writing the query.</p>
+
+<p>Calcite could perhaps solve this generalizing <code>GROUP BY</code> syntax, but we would
+be destroying the principle that an input row into a <code>GROUP BY</code> appears in
+precisely one output row.</p>
+
+<p>Calcite’s SQL extensions for streaming queries are evolving. As we learn more
+about how people wish to query streams, we plan to make the language more
+expressive while remaining compatible with standard SQL and consistent with
+its principles, look and feel.</p>
+
+<h2 id="sorting">Sorting</h2>
+
+<p>The story for <code>ORDER BY</code> is similar to <code>GROUP BY</code>.
+The syntax looks like regular SQL, but Calcite must be sure that it can deliver
+timely results. It therefore requires a monotonic expression on the leading edge
+of your <code>ORDER BY</code> key.</p>
+
+<p>```sql
+SELECT STREAM FLOOR(rowtime TO hour) AS rowtime, productId, orderId, units
+FROM Orders
+ORDER BY FLOOR(rowtime TO hour) ASC, units DESC;</p>
+
+<p>rowtime | productId | orderId | units
+———-+———–+———+——-
+ 10:00:00 |        30 |       8 |    20
+ 10:00:00 |        30 |       5 |     4
+ 10:00:00 |        20 |       7 |     2
+ 10:00:00 |        10 |       6 |     1
+ 11:00:00 |        40 |      11 |    12
+ 11:00:00 |        10 |       9 |     6
+ 11:00:00 |        10 |      12 |     4
+ 11:00:00 |        10 |      10 |     1
+```</p>
+
+<p>Most queries will return results in the order that they were inserted,
+because the engine is using streaming algorithms, but you should not rely on it.
+For example, consider this:</p>
+
+<p>```sql
+SELECT STREAM *
+FROM Orders
+WHERE productId = 10
+UNION ALL
+SELECT STREAM *
+FROM Orders
+WHERE productId = 30;</p>
+
+<p>rowtime | productId | orderId | units
+———-+———–+———+——-
+ 10:17:05 |        10 |       6 |     1
+ 10:17:00 |        30 |       5 |     4
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:04:00 |        10 |      10 |     1
+ 11:24:11 |        10 |      12 |     4
+```</p>
+
+<p>The rows with <code>productId</code> = 30 are apparently out of order, probably because
+the <code>Orders</code> stream was partitioned on <code>productId</code> and the partitioned streams
+sent their data at different times.</p>
+
+<p>If you require a particular ordering, add an explicit <code>ORDER BY</code>:</p>
+
+<p>```sql
+SELECT STREAM *
+FROM Orders
+WHERE productId = 10
+UNION ALL
+SELECT STREAM *
+FROM Orders
+WHERE productId = 30
+ORDER BY rowtime;</p>
+
+<p>rowtime | productId | orderId | units
+———-+———–+———+——-
+ 10:17:00 |        30 |       5 |     4
+ 10:17:05 |        10 |       6 |     1
+ 10:18:07 |        30 |       8 |    20
+ 11:02:00 |        10 |       9 |     6
+ 11:04:00 |        10 |      10 |     1
+ 11:24:11 |        10 |      12 |     4
+```</p>
+
+<p>Calcite will probably implement the <code>UNION ALL</code> by merging using <code>rowtime</code>,
+which is only slightly less efficient.</p>
+
+<p>You only need to add an <code>ORDER BY</code> to the outermost query. If you need to,
+say, perform <code>GROUP BY</code> after a <code>UNION ALL</code>, Calcite will add an <code>ORDER BY</code>
+implicitly, in order to make the GROUP BY algorithm possible.</p>
+
+<h2 id="table-constructor">Table constructor</h2>
+
+<p>The <code>VALUES</code> clause creates an inline table with a given set of rows.</p>
+
+<p>Streaming is disallowed. The set of rows never changes, and therefore a stream
+would never return any rows.</p>
+
+<p>```sql
+&gt; SELECT STREAM * FROM (VALUES (1, ‘abc’));</p>
+
+<p>ERROR: Cannot stream VALUES
+```</p>
+
+<h2 id="sliding-windows">Sliding windows</h2>
+
+<p>Standard SQL features so-called “analytic functions” that can be used in the
+<code>SELECT</code> clause. Unlike <code>GROUP BY</code>, these do not collapse records. For each
+record that goes in, one record comes out. But the aggregate function is based
+on a window of many rows.</p>
+
+<p>Let’s look at an example.</p>
+
+<p><code>sql
+SELECT STREAM rowtime,
+  productId,
+  units,
+  SUM(units) OVER (ORDER BY rowtime RANGE INTERVAL '1' HOUR PRECEDING) unitsLastHour
+FROM Orders;
+</code></p>
+
+<p>The feature packs a lot of power with little effort. You can have multiple
+functions in the <code>SELECT</code> clause, based on multiple window specifications.</p>
+
+<p>The following example returns orders whose average order size over the last
+10 minutes is greater than the average order size for the last week.</p>
+
+<p><code>sql
+SELECT STREAM *
+FROM (
+  SELECT STREAM rowtime,
+    productId,
+    units,
+    AVG(units) OVER product (RANGE INTERVAL '10' MINUTE PRECEDING) AS m10,
+    AVG(units) OVER product (RANGE INTERVAL '7' DAY PRECEDING) AS d7
+  FROM Orders
+  WINDOW product AS (
+    ORDER BY rowtime
+    PARTITION BY productId))
+WHERE m10 &gt; d7;
+</code></p>
+
+<p>For conciseness, here we use a syntax where you partially define a window
+using a <code>WINDOW</code> clause and then refine the window in each <code>OVER</code> clause.
+You could also define all windows in the <code>WINDOW</code> clause, or all windows inline,
+if you wish.</p>
+
+<p>But the real power goes beyond syntax. Behind the scenes, this query is
+maintaining two tables, and adding and removing values from sub-totals using
+with FIFO queues. But you can access those tables without introducing a join
+into the query.</p>
+
+<p>Some other features of the windowed aggregation syntax:
+* You can define windows based on row count.
+* The window can reference rows that have not yet arrived.
+  (The stream will wait until they have arrived).
+* You can compute order-dependent functions such as <code>RANK</code> and median.</p>
+
+<h2 id="cascading-windows">Cascading windows</h2>
+
+<p>What if we want a query that returns a result for every record, like a
+sliding window, but resets totals on a fixed time period, like a
+tumbling window? Such a pattern is called a <em>cascading window</em>. Here
+is an example:</p>
+
+<p><code>sql
+SELECT STREAM rowtime,
+  productId,
+  units,
+  SUM(units) OVER (PARTITION BY FLOOR(rowtime TO HOUR)) AS unitsSinceTopOfHour
+FROM Orders;
+</code></p>
+
+<p>It looks similar to a sliding window query, but the monotonic
+expression occurs within the <code>PARTITION BY</code> clause of the window. As
+the rowtime moves from from 10:59:59 to 11:00:00, <code>FLOOR(rowtime TO
+HOUR)</code> changes from 10:00:00 to 11:00:00, and therefore a new
+partition starts. The first row to arrive in the new hour will start a
+new total; the second row will have a total that consists of two rows,
+and so on.</p>
+
+<p>Calcite knows that the old partition will never be used again, so
+removes all sub-totals for that partition from its internal storage.</p>
+
+<p>Analytic functions that using cascading and sliding windows can be
+combined in the same query.</p>
+
+<h2 id="state-of-the-stream">State of the stream</h2>
+
+<p>Not all concepts in this article have been implemented in Calcite.
+And others may be implemented in Calcite but not in a particular adapter
+such as Samza SQL [<a href="#ref3">3</a>].</p>
+
+<h3 id="implemented">Implemented</h3>
+<ul>
+  <li>Streaming SELECT, WHERE, GROUP BY, HAVING, UNION ALL, ORDER BY</li>
+  <li>FLOOR and CEILING functions</li>
+  <li>Monotonicity</li>
+  <li>Streaming VALUES is disallowed</li>
+</ul>
+
+<h3 id="not-implemented">Not implemented</h3>
+<ul>
+  <li>Stream-to-stream JOIN</li>
+  <li>Stream-to-table JOIN</li>
+  <li>Stream on view</li>
+  <li>Streaming UNION ALL with ORDER BY (merge)</li>
+  <li>Relational query on stream</li>
+  <li>Streaming windowed aggregation (sliding and cascading windows)</li>
+  <li>Check that STREAM in sub-queries and views is ignored</li>
+  <li>Check that streaming ORDER BY cannot have OFFSET or LIMIT</li>
+  <li>Limited history; at run time, check that there is sufficient history
+to run the query.</li>
+</ul>
+
+<h3 id="to-do-in-this-document">To do in this document</h3>
+<ul>
+  <li>Re-visit whether you can stream VALUES</li>
+  <li>OVER clause to define window on stream</li>
+  <li>Windowed aggregation</li>
+  <li>Punctuation</li>
+  <li>Stream-to-table join
+** Stream-to-table join where table is changing</li>
+  <li>Stream-to-stream join</li>
+  <li>Relational queries on streams (e.g. “pie chart” query)</li>
+  <li>Diagrams for various window types</li>
+</ul>
+
+<h2 id="references">References</h2>
+
+<ul>
+  <li>[<a name="ref1">1</a>]
+<a href="http://ilpubs.stanford.edu:8090/758/">Arasu, Arvind and Babu,
+Shivnath and Widom, Jennifer (2003) The CQL Continuous Query
+Language: Semantic Foundations and Query Execution</a>.</li>
+  <li>[<a name="ref2">2</a>]
+<a href="http://kafka.apache.org/documentation.html">Apache Kafka</a>.</li>
+  <li>[<a name="ref3">3</a>] <a href="http://samza.apache.org">Apache Samza</a>.</li>
+</ul>
+
+          
+
+
+
+
+
+  
+  
+
+  
+  
+
+  
+  
+
+  
+  
+
+  
+  
+
+  
+  
+    <div class="section-nav">
+      <div class="left align-right">
+          
+            
+            
+            <a href="/docs/avatica.html" class="prev">Back</a>
+          
+      </div>
+      <div class="right align-left">
+          
+            
+            
+            <a href="/docs/lattice.html" class="next">Next</a>
+          
+      </div>
+    </div>
+    <div class="clear"></div>
+    
+
+        </article>
+      </div>
+
+      <div class="unit one-fifth hide-on-mobiles">
+  <aside>
+    
+    <h4>Overview</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/index.html">Background</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/tutorial.html">Tutorial</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+      <li class=""><a href="/docs/algebra.html">Algebra</a></li>
+      
+
+
+</ul>
+
+    
+    <h4>Advanced</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+      <li class=""><a href="/docs/adapter.html">Adapters</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/avatica.html">Avatica</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class="current"><a href="/docs/stream.html">Streaming</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/lattice.html">Lattices</a></li>
+      
+
+
+</ul>
+
+    
+    <h4>Reference</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/reference.html">SQL language</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/model.html">JSON models</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/howto.html">HOWTO</a></li>
+      
+
+
+</ul>
+
+    
+    <h4>Meta</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/downloads.html">Downloads</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/history.html">History</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/contributing.html">Contributing</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/api.html">API</a></li>
+      
+
+
+</ul>
+
+    
+  </aside>
+</div>
+
+
+      <div class="clear"></div>
+
+    </div>
+  </section>
+
+
+  <footer role="contentinfo">
+  <p>The contents of this website are &copy;&nbsp;2015
+     <a href="https://www.apache.org/">Apache Software Foundation</a>
+     under the terms of
+     the <a href="https://www.apache.org/licenses/LICENSE-2.0.html">
+     Apache&nbsp;License&nbsp;v2</a>. Apache Calcite and its logo are
+     trademarks of the Apache Software Foundation.</p>
+
+  <p>Apache Calcite is an effort undergoing incubation at The Apache
+      Software Foundation (ASF), sponsored by the Apache
+      Incubator. Incubation is required of all newly accepted projects
+      until a further review indicates that the infrastructure,
+      communications, and decision making process have stabilized in a
+      manner consistent with other successful ASF projects. While
+      incubation status is not necessarily a reflection of the
+      completeness or stability of the code, it does indicate that the
+      project has yet to be fully endorsed by the ASF.</p>
+  
+</footer>
+
+  <script>
+  var anchorForId = function (id) {
+    var anchor = document.createElement("a");
+    anchor.className = "header-link";
+    anchor.href      = "#" + id;
+    anchor.innerHTML = "<span class=\"sr-only\">Permalink</span><i class=\"fa fa-link\"></i>";
+    anchor.title = "Permalink";
+    return anchor;
+  };
+
+  var linkifyAnchors = function (level, containingElement) {
+    var headers = containingElement.getElementsByTagName("h" + level);
+    for (var h = 0; h < headers.length; h++) {
+      var header = headers[h];
+
+      if (typeof header.id !== "undefined" && header.id !== "") {
+        header.appendChild(anchorForId(header.id));
+      }
+    }
+  };
+
+  document.onreadystatechange = function () {
+    if (this.readyState === "complete") {
+      var contentBlock = document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
+      if (!contentBlock) {
+        return;
+      }
+      for (var level = 1; level <= 6; level++) {
+        linkifyAnchors(level, contentBlock);
+      }
+    }
+  };
+</script>
+
+
+</body>
+</html>

Added: incubator/calcite/site/docs/tutorial.html
URL: http://svn.apache.org/viewvc/incubator/calcite/site/docs/tutorial.html?rev=1682430&view=auto
==============================================================================
--- incubator/calcite/site/docs/tutorial.html (added)
+++ incubator/calcite/site/docs/tutorial.html Fri May 29 11:48:34 2015
@@ -0,0 +1,1839 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <title>Tutorial</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <meta name="generator" content="Jekyll v2.4.0">
+  <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic,900">
+  <link rel="stylesheet" href="/css/screen.css">
+  <link rel="icon" type="image/x-icon" href="/favicon.ico">
+  <!--[if lt IE 9]>
+  <script src="/js/html5shiv.min.js"></script>
+  <script src="/js/respond.min.js"></script>
+  <![endif]-->
+</head>
+
+
+<body class="wrap">
+  <header role="banner">
+  <nav class="mobile-nav show-on-mobiles">
+    <ul>
+  <li class="">
+    <a href="/">Home</a>
+  </li>
+  <li class="current">
+    <a href="/docs/">Documentation</a>
+  </li>
+  <li class="">
+    <a href="/talks/">Talks</a>
+  </li>
+  <li class="">
+    <a href="/news/">News</a>
+  </li>
+  <li class="">
+    <a href="/help/">Help</a>
+  </li>
+  <li class="">
+    <a href="/develop/">Develop</a>
+  </li>
+</ul>
+
+  </nav>
+  <div class="grid">
+    <div class="unit one-third center-on-mobiles">
+      <h1>
+        <a href="/">
+          <span class="sr-only">Apache Calcite</span>
+          <img src="/img/logo.png" width="226" height="140" alt="Calcite Logo">
+        </a>
+      </h1>
+    </div>
+    <nav class="main-nav unit two-thirds hide-on-mobiles">
+      <ul>
+  <li class="">
+    <a href="/">Home</a>
+  </li>
+  <li class="current">
+    <a href="/docs/">Documentation</a>
+  </li>
+  <li class="">
+    <a href="/talks/">Talks</a>
+  </li>
+  <li class="">
+    <a href="/news/">News</a>
+  </li>
+  <li class="">
+    <a href="/help/">Help</a>
+  </li>
+  <li class="">
+    <a href="/develop/">Develop</a>
+  </li>
+</ul>
+
+    </nav>
+  </div>
+</header>
+
+
+    <section class="docs">
+    <div class="grid">
+
+      <div class="docs-nav-mobile unit whole show-on-mobiles">
+  <select onchange="if (this.value) window.location.href=this.value">
+    <option value="">Navigate the docs…</option>
+    
+    <optgroup label="Overview">
+      
+
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/index.html">Background</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/tutorial.html">Tutorial</option>
+    
+  
+
+  
+
+  
+    
+  
+    
+      <option value="/docs/algebra.html">Algebra</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+    <optgroup label="Advanced">
+      
+
+
+  
+
+  
+    
+      <option value="/docs/adapter.html">Adapters</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/avatica.html">Avatica</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/stream.html">Streaming</option>
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/lattice.html">Lattices</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+    <optgroup label="Reference">
+      
+
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/reference.html">SQL language</option>
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/model.html">JSON models</option>
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/howto.html">HOWTO</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+    <optgroup label="Meta">
+      
+
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/downloads.html">Downloads</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/history.html">History</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <option value="/docs/contributing.html">Contributing</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+  
+
+  
+    
+  
+    
+  
+    
+      <option value="/docs/api.html">API</option>
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+
+
+    </optgroup>
+    
+  </select>
+</div>
+
+
+      <div class="unit four-fifths">
+        <article>
+          <h1>Tutorial</h1>
+          <!--
+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.
+-->
+
+<p>This is a step-by-step tutorial that shows how to build and connect to
+Calcite. It uses a simple adapter that makes a directory of CSV files
+appear to be a schema containing tables. Calcite does the rest, and
+provides a full SQL interface.</p>
+
+<p>Calcite-example-CSV is a fully functional adapter for
+Calcite that reads
+text files in
+<a href="http://en.wikipedia.org/wiki/Comma-separated_values">CSV
+(comma-separated values)</a> format. It is remarkable that a couple of
+hundred lines of Java code are sufficient to provide full SQL query
+capability.</p>
+
+<p>CSV also serves as a template for building adapters to other
+data formats. Even though there are not many lines of code, it covers
+several important concepts:
+* user-defined schema using SchemaFactory and Schema interfaces;
+* declaring schemas in a model JSON file;
+* declaring views in a model JSON file;
+* user-defined table using the Table interface;
+* determining the record type of a table;
+* a simple implementation of Table, using the ScannableTable interface, that
+  enumerates all rows directly;
+* a more advanced implementation that implements FilterableTable, and can
+  filter out rows according to simple predicates;
+* advanced implementation of Table, using TranslatableTable, that translates
+  to relational operators using planner rules.</p>
+
+<h2 id="download-and-build">Download and build</h2>
+
+<p>You need Java (1.7 or higher; 1.8 preferred), git and maven (3.2.1 or later).</p>
+
+<p><code>bash
+$ git clone https://github.com/apache/incubator-calcite.git
+$ cd incubator-calcite
+$ mvn install -DskipTests -Dcheckstyle.skip=true
+$ cd example/csv
+</code></p>
+
+<h2 id="first-queries">First queries</h2>
+
+<p>Now let’s connect to Calcite using
+<a href="https://github.com/julianhyde/sqlline">sqlline</a>, a SQL shell
+that is included in this project.</p>
+
+<p><code>bash
+$ ./sqlline
+sqlline&gt; !connect jdbc:calcite:model=target/test-classes/model.json admin admin
+</code></p>
+
+<p>(If you are running Windows, the command is <code>sqlline.bat</code>.)</p>
+
+<p>Execute a metadata query:</p>
+
+<p><code>bash
+sqlline&gt; !tables
++------------+--------------+-------------+---------------+----------+------+
+| TABLE_CAT  | TABLE_SCHEM  | TABLE_NAME  |  TABLE_TYPE   | REMARKS  | TYPE |
++------------+--------------+-------------+---------------+----------+------+
+| null       | SALES        | DEPTS       | TABLE         | null     | null |
+| null       | SALES        | EMPS        | TABLE         | null     | null |
+| null       | SALES        | HOBBIES     | TABLE         | null     | null |
+| null       | metadata     | COLUMNS     | SYSTEM_TABLE  | null     | null |
+| null       | metadata     | TABLES      | SYSTEM_TABLE  | null     | null |
++------------+--------------+-------------+---------------+----------+------+
+</code></p>
+
+<p>(JDBC experts, note: sqlline’s <code>!tables</code> command is just executing
+<a href="http://docs.oracle.com/javase/7/docs/api/java/sql/DatabaseMetaData.html#getTables(java.lang.String, java.lang.String, java.lang.String, java.lang.String[])"><code>DatabaseMetaData.getTables()</code></a>
+behind the scenes.
+It has other commands to query JDBC metadata, such as <code>!columns</code> and <code>!describe</code>.)</p>
+
+<p>As you can see there are 5 tables in the system: tables
+<code>EMPS</code>, <code>DEPTS</code> and <code>HOBBIES</code> in the current
+<code>SALES</code> schema, and <code>COLUMNS</code> and
+<code>TABLES</code> in the system <code>metadata</code> schema. The
+system tables are always present in Calcite, but the other tables are
+provided by the specific implementation of the schema; in this case,
+the <code>EMPS</code> and <code>DEPTS</code> tables are based on the
+<code>EMPS.csv</code> and <code>DEPTS.csv</code> files in the
+<code>target/test-classes</code> directory.</p>
+
+<p>Let’s execute some queries on those tables, to show that Calcite is providing
+a full implementation of SQL. First, a table scan:</p>
+
+<p><code>bash
+sqlline&gt; SELECT * FROM emps;
++--------+--------+---------+---------+----------------+--------+-------+---+
+| EMPNO  |  NAME  | DEPTNO  | GENDER  |      CITY      | EMPID  |  AGE  | S |
++--------+--------+---------+---------+----------------+--------+-------+---+
+| 100    | Fred   | 10      |         |                | 30     | 25    | t |
+| 110    | Eric   | 20      | M       | San Francisco  | 3      | 80    | n |
+| 110    | John   | 40      | M       | Vancouver      | 2      | null  | f |
+| 120    | Wilma  | 20      | F       |                | 1      | 5     | n |
+| 130    | Alice  | 40      | F       | Vancouver      | 2      | null  | f |
++--------+--------+---------+---------+----------------+--------+-------+---+
+</code></p>
+
+<p>Now JOIN and GROUP BY:</p>
+
+<p><code>bash
+sqlline&gt; SELECT d.name, COUNT(*)
+. . . .&gt; FROM emps AS e JOIN depts AS d ON e.deptno = d.deptno
+. . . .&gt; GROUP BY d.name;
++------------+---------+
+|    NAME    | EXPR$1  |
++------------+---------+
+| Sales      | 1       |
+| Marketing  | 2       |
++------------+---------+
+</code></p>
+
+<p>Last, the VALUES operator generates a single row, and is a convenient
+way to test expressions and SQL built-in functions:</p>
+
+<p><code>bash
+sqlline&gt; VALUES CHAR_LENGTH('Hello, ' || 'world!');
++---------+
+| EXPR$0  |
++---------+
+| 13      |
++---------+
+</code></p>
+
+<p>Calcite has many other SQL features. We don’t have time to cover them
+here. Write some more queries to experiment.</p>
+
+<h2 id="schema-discovery">Schema discovery</h2>
+
+<p>Now, how did Calcite find these tables? Remember, core Calcite does not
+know anything about CSV files. (As a “database without a storage
+layer”, Calcite doesn’t know about any file formats.) Calcite knows about
+those tables because we told it to run code in the calcite-example-csv
+project.</p>
+
+<p>There are a couple of steps in that chain. First, we define a schema
+based on a schema factory class in a model file. Then the schema
+factory creates a schema, and the schema creates several tables, each
+of which knows how to get data by scanning a CSV file. Last, after
+Calcite has parsed the query and planned it to use those tables, Calcite
+invokes the tables to read the data as the query is being
+executed. Now let’s look at those steps in more detail.</p>
+
+<p>On the JDBC connect string we gave the path of a model in JSON
+format. Here is the model:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  defaultSchema: 'SALES',
+  schemas: [
+    {
+      name: 'SALES',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
+      operand: {
+        directory: 'target/test-classes/sales'
+      }
+    }
+  ]
+}
+</code></p>
+
+<p>The model defines a single schema called ‘SALES’. The schema is
+powered by a plugin class,
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchemaFactory.java">org.apache.calcite.adapter.csv.CsvSchemaFactory</a>,
+which is part of the
+calcite-example-csv project and implements the Calcite interface
+<a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/SchemaFactory.html">SchemaFactory</a>.
+Its <code>create</code> method instantiates a
+schema, passing in the <code>directory</code> argument from the model file:</p>
+
+<p><code>java
+public Schema create(SchemaPlus parentSchema, String name,
+    Map&lt;String, Object&gt; operand) {
+  String directory = (String) operand.get("directory");
+  String flavorName = (String) operand.get("flavor");
+  CsvTable.Flavor flavor;
+  if (flavorName == null) {
+    flavor = CsvTable.Flavor.SCANNABLE;
+  } else {
+    flavor = CsvTable.Flavor.valueOf(flavorName.toUpperCase());
+  }
+  return new CsvSchema(
+      new File(directory),
+      flavor);
+}
+</code></p>
+
+<p>Driven by the model, the schema factory instantiates a single schema
+called ‘SALES’.  The schema is an instance of
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvSchema.java">org.apache.calcite.adapter.csv.CsvSchema</a>
+and implements the Calcite interface <a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/Schema.html">Schema</a>.</p>
+
+<p>A schema’s job is to produce a list of tables. (It can also list sub-schemas and
+table-functions, but these are advanced features and calcite-example-csv does
+not support them.) The tables implement Calcite’s
+<a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/Table.html">Table</a>
+interface. <code>CsvSchema</code> produces tables that are instances of
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTable.java">CsvTable</a>
+and its sub-classes.</p>
+
+<p>Here is the relevant code from <code>CsvSchema</code>, overriding the
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/impl/AbstractSchema.html#getTableMap()">getTableMap()</a></code>
+method in the <code>AbstractSchema</code> base class.</p>
+
+<p>```java
+protected Map&lt;String, Table&gt; getTableMap() {
+  // Look for files in the directory ending in “.csv”, “.csv.gz”, “.json”,
+  // “.json.gz”.
+  File[] files = directoryFile.listFiles(
+      new FilenameFilter() {
+        public boolean accept(File dir, String name) {
+          final String nameSansGz = trim(name, “.gz”);
+          return nameSansGz.endsWith(“.csv”)
+              || nameSansGz.endsWith(“.json”);
+        }
+      });
+  if (files == null) {
+    System.out.println(“directory “ + directoryFile + “ not found”);
+    files = new File[0];
+  }
+  // Build a map from table name to table; each file becomes a table.
+  final ImmutableMap.Builder&lt;String, Table&gt; builder = ImmutableMap.builder();
+  for (File file : files) {
+    String tableName = trim(file.getName(), “.gz”);
+    final String tableNameSansJson = trimOrNull(tableName, “.json”);
+    if (tableNameSansJson != null) {
+      JsonTable table = new JsonTable(file);
+      builder.put(tableNameSansJson, table);
+      continue;
+    }
+    tableName = trim(tableName, “.csv”);
+    final Table table = createTable(file);
+    builder.put(tableName, table);
+  }
+  return builder.build();
+}</p>
+
+<p>/** Creates different sub-type of table based on the “flavor” attribute. */
+private Table createTable(File file) {
+  switch (flavor) {
+  case TRANSLATABLE:
+    return new CsvTranslatableTable(file, null);
+  case SCANNABLE:
+    return new CsvScannableTable(file, null);
+  case FILTERABLE:
+    return new CsvFilterableTable(file, null);
+  default:
+    throw new AssertionError(“Unknown flavor “ + flavor);
+  }
+}
+```</p>
+
+<p>The schema scans the directory and finds all files whose name ends
+with “.csv” and creates tables for them. In this case, the directory
+is <code>target/test-classes/sales</code> and contains files
+<code>EMPS.csv</code> and <code>DEPTS.csv</code>, which these become
+the tables <code>EMPS</code> and <code>DEPTS</code>.</p>
+
+<h2 id="tables-and-views-in-schemas">Tables and views in schemas</h2>
+
+<p>Note how we did not need to define any tables in the model; the schema
+generated the tables automatically.</p>
+
+<p>You can define extra tables,
+beyond those that are created automatically,
+using the <code>tables</code> property of a schema.</p>
+
+<p>Let’s see how to create
+an important and useful type of table, namely a view.</p>
+
+<p>A view looks like a table when you are writing a query, but it doesn’t store data.
+It derives its result by executing a query.
+The view is expanded while the query is being planned, so the query planner
+can often perform optimizations like removing expressions from the SELECT
+clause that are not used in the final result.</p>
+
+<p>Here is a schema that defines a view:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  defaultSchema: 'SALES',
+  schemas: [
+    {
+      name: 'SALES',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.csv.CsvSchemaFactory',
+      operand: {
+        directory: 'target/test-classes/sales'
+      },
+      tables: [
+        {
+          name: 'FEMALE_EMPS',
+          type: 'view',
+          sql: 'SELECT * FROM emps WHERE gender = \'F\''
+        }
+      ]
+    }
+  ]
+}
+</code></p>
+
+<p>The line <code>type: 'view'</code> tags <code>FEMALE_EMPS</code> as a view,
+as opposed to a regular table or a custom table.
+Note that single-quotes within the view definition are escaped using a
+back-slash, in the normal way for JSON.</p>
+
+<p>JSON doesn’t make it easy to author long strings, so Calcite supports an
+alternative syntax. If your view has a long SQL statement, you can instead
+supply a list of lines rather than a single string:</p>
+
+<p><code>json
+        {
+          name: 'FEMALE_EMPS',
+          type: 'view',
+          sql: [
+            'SELECT * FROM emps',
+            'WHERE gender = \'F\''
+          ]
+        }
+</code></p>
+
+<p>Now we have defined a view, we can use it in queries just as if it were a table:</p>
+
+<p><code>sql
+sqlline&gt; SELECT e.name, d.name FROM female_emps AS e JOIN depts AS d on e.deptno = d.deptno;
++--------+------------+
+|  NAME  |    NAME    |
++--------+------------+
+| Wilma  | Marketing  |
++--------+------------+
+</code></p>
+
+<h2 id="custom-tables">Custom tables</h2>
+
+<p>Custom tables are tables whose implementation is driven by user-defined code.
+They don’t need to live in a custom schema.</p>
+
+<p>There is an example in <code>model-with-custom-table.json</code>:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  defaultSchema: 'CUSTOM_TABLE',
+  schemas: [
+    {
+      name: 'CUSTOM_TABLE',
+      tables: [
+        {
+          name: 'EMPS',
+          type: 'custom',
+          factory: 'org.apache.calcite.adapter.csv.CsvTableFactory',
+          operand: {
+            file: 'target/test-classes/sales/EMPS.csv.gz',
+            flavor: "scannable"
+          }
+        }
+      ]
+    }
+  ]
+}
+</code></p>
+
+<p>We can query the table in the usual way:</p>
+
+<p><code>sql
+sqlline&gt; !connect jdbc:calcite:model=target/test-classes/model-with-custom-table.json admin admin
+sqlline&gt; SELECT empno, name FROM custom_table.emps;
++--------+--------+
+| EMPNO  |  NAME  |
++--------+--------+
+| 100    | Fred   |
+| 110    | Eric   |
+| 110    | John   |
+| 120    | Wilma  |
+| 130    | Alice  |
++--------+--------+
+</code></p>
+
+<p>The schema is a regular one, and contains a custom table powered by
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableFactory.java">org.apache.calcite.adapter.csv.CsvTableFactory</a>,
+which implements the Calcite interface
+<a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/TableFactory.html">TableFactory</a>.
+Its <code>create</code> method instantiates a <code>CsvScannableTable</code>,
+passing in the <code>file</code> argument from the model file:</p>
+
+<p><code>java
+public CsvTable create(SchemaPlus schema, String name,
+    Map&lt;String, Object&gt; map, RelDataType rowType) {
+  String fileName = (String) map.get("file");
+  final File file = new File(fileName);
+  final RelProtoDataType protoRowType =
+      rowType != null ? RelDataTypeImpl.proto(rowType) : null;
+  return new CsvScannableTable(file, protoRowType);
+}
+</code></p>
+
+<p>Implementing a custom table is often a simpler alternative to implementing
+a custom schema. Both approaches might end up creating a similar implementation
+of the <code>Table</code> interface, but for the custom table you don’t
+need to implement metadata discovery. (<code>CsvTableFactory</code>
+creates a <code>CsvScannableTable</code>, just as <code>CsvSchema</code> does,
+but the table implementation does not scan the filesystem for .csv files.)</p>
+
+<p>Custom tables require more work for the author of the model (the author
+needs to specify each table and its file explicitly) but also give the author
+more control (say, providing different parameters for each table).</p>
+
+<h2 id="comments-in-models">Comments in models</h2>
+
+<p>Models can include comments using <code>/* ... */</code> and <code>//</code> syntax:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  /* Multi-line
+     comment. */
+  defaultSchema: 'CUSTOM_TABLE',
+  // Single-line comment.
+  schemas: [
+    ..
+  ]
+}
+</code></p>
+
+<p>(Comments are not standard JSON, but are a harmless extension.)</p>
+
+<h2 id="optimizing-queries-using-planner-rules">Optimizing queries using planner rules</h2>
+
+<p>The table implementations we have seen so far are fine as long as the tables
+don’t contain a great deal of data. But if your customer table has, say, a
+hundred columns and a million rows, you would rather that the system did not
+retrieve all of the data for every query. You would like Calcite to negotiate
+with the adapter and find a more efficient way of accessing the data.</p>
+
+<p>This negotiation is a simple form of query optimization. Calcite supports query
+optimization by adding <i>planner rules</i>. Planner rules operate by
+looking for patterns in the query parse tree (for instance a project on top
+of a certain kind of table), and</p>
+
+<p>Planner rules are also extensible, like schemas and tables. So, if you have a
+data store that you want to access via SQL, you first define a custom table or
+schema, and then you define some rules to make the access efficient.</p>
+
+<p>To see this in action, let’s use a planner rule to access
+a subset of columns from a CSV file. Let’s run the same query against two very
+similar schemas:</p>
+
+<p><code>sql
+sqlline&gt; !connect jdbc:calcite:model=target/test-classes/model.json admin admin
+sqlline&gt; explain plan for select name from emps;
++-----------------------------------------------------+
+| PLAN                                                |
++-----------------------------------------------------+
+| EnumerableCalcRel(expr#0..9=[{inputs}], NAME=[$t1]) |
+|   EnumerableTableAccessRel(table=[[SALES, EMPS]])   |
++-----------------------------------------------------+
+sqlline&gt; !connect jdbc:calcite:model=target/test-classes/smart.json admin admin
+sqlline&gt; explain plan for select name from emps;
++-----------------------------------------------------+
+| PLAN                                                |
++-----------------------------------------------------+
+| EnumerableCalcRel(expr#0..9=[{inputs}], NAME=[$t1]) |
+|   CsvTableScan(table=[[SALES, EMPS]])               |
++-----------------------------------------------------+
+</code></p>
+
+<p>What causes the difference in plan? Let’s follow the trail of evidence. In the
+<code>smart.json</code> model file, there is just one extra line:</p>
+
+<p><code>json
+flavor: "translatable"
+</code></p>
+
+<p>This causes a <code>CsvSchema</code> to be created with
+<code>flavor = TRANSLATABLE</code>,
+and its <code>createTable</code> method creates instances of
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTranslatableTable.java">CsvTranslatableTable</a>
+rather than a <code>CsvScannableTable</code>.</p>
+
+<p><code>CsvTranslatableTable</code> implements the
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/schema/TranslatableTable.html#toRel()">TranslatableTable.toRel()</a></code>
+method to create
+<a href="../example/csv/src/main/java/org/apache/calcite/adapter/csv/CsvTableScan.java">CsvTableScan</a>.
+Table scans are the leaves of a query operator tree.
+The usual implementation is
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/adapter/enumerable/EnumerableTableScan.html">EnumerableTableScan</a></code>,
+but we have created a distinctive sub-type that will cause rules to fire.</p>
+
+<p>Here is the rule in its entirety:</p>
+
+<p>```java
+public class CsvProjectTableScanRule extends RelOptRule {
+  public static final CsvProjectTableScanRule INSTANCE =
+      new CsvProjectTableScanRule();</p>
+
+<p>private CsvProjectTableScanRule() {
+    super(
+        operand(Project.class,
+            operand(CsvTableScan.class, none())),
+        “CsvProjectTableScanRule”);
+  }</p>
+
+<p>@Override
+  public void onMatch(RelOptRuleCall call) {
+    final Project project = call.rel(0);
+    final CsvTableScan scan = call.rel(1);
+    int[] fields = getProjectFields(project.getProjects());
+    if (fields == null) {
+      // Project contains expressions more complex than just field references.
+      return;
+    }
+    call.transformTo(
+        new CsvTableScan(
+            scan.getCluster(),
+            scan.getTable(),
+            scan.csvTable,
+            fields));
+  }</p>
+
+<p>private int[] getProjectFields(List<rexnode> exps) {
+    final int[] fields = new int[exps.size()];
+    for (int i = 0; i &lt; exps.size(); i++) {
+      final RexNode exp = exps.get(i);
+      if (exp instanceof RexInputRef) {
+        fields[i] = ((RexInputRef) exp).getIndex();
+      } else {
+        return null; // not a simple projection
+      }
+    }
+    return fields;
+  }
+}
+```</rexnode></p>
+
+<p>The constructor declares the pattern of relational expressions that will cause
+the rule to fire.</p>
+
+<p>The <code>onMatch</code> method generates a new relational expression and calls
+<code><a href="http://www.hydromatic.net/calcite/apidocs/org/apache/calcite/plan/RelOptRuleCall.html#transformTo(org.apache.calcite.rel.RelNode)">RelOptRuleCall.transformTo()</a></code>
+to indicate that the rule has fired successfully.</p>
+
+<h2 id="the-query-optimization-process">The query optimization process</h2>
+
+<p>There’s a lot to say about how clever Calcite’s query planner is, but we won’t
+say it here. The cleverness is designed to take the burden off you, the writer
+of planner rules.</p>
+
+<p>First, Calcite doesn’t fire rules in a prescribed order. The query optimization
+process follows many branches of a branching tree, just like a chess playing
+program examines many possible sequences of moves. If rules A and B both match a
+given section of the query operator tree, then Calcite can fire both.</p>
+
+<p>Second, Calcite uses cost in choosing between plans, but the cost model doesn’t
+prevent rules from firing which may seem to be more expensive in the short term.</p>
+
+<p>Many optimizers have a linear optimization scheme. Faced with a choice between
+rule A and rule B, as above, such an optimizer needs to choose immediately. It
+might have a policy such as “apply rule A to the whole tree, then apply rule B
+to the whole tree”, or apply a cost-based policy, applying the rule that
+produces the cheaper result.</p>
+
+<p>Calcite doesn’t require such compromises.
+This makes it simple to combine various sets of rules.
+If, say you want to combine rules to recognize materialized views with rules to
+read from CSV and JDBC source systems, you just give Calcite the set of all
+rules and tell it to go at it.</p>
+
+<p>Calcite does use a cost model. The cost model decides which plan to ultimately
+use, and sometimes to prune the search tree to prevent the search space from
+exploding, but it never forces you to choose between rule A and rule B. This is
+important, because it avoids falling into local minima in the search space that
+are not actually optimal.</p>
+
+<p>Also (you guessed it) the cost model is pluggable, as are the table and query
+operator statistics it is based upon. But that can be a subject for later.</p>
+
+<h2 id="jdbc-adapter">JDBC adapter</h2>
+
+<p>The JDBC adapter maps a schema in a JDBC data source as a Calcite schema.</p>
+
+<p>For example, this schema reads from a MySQL “foodmart” database:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  defaultSchema: 'FOODMART',
+  schemas: [
+    {
+      name: 'FOODMART',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
+      operand: {
+        jdbcDriver: 'com.mysql.jdbc.Driver',
+        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
+        jdbcUser: 'foodmart',
+        jdbcPassword: 'foodmart'
+      }
+    }
+  ]
+}
+</code></p>
+
+<p>(The FoodMart database will be familiar to those of you who have used
+the Mondrian OLAP engine, because it is Mondrian’s main test data
+set. To load the data set, follow <a href="http://mondrian.pentaho.com/documentation/installation.php#2_Set_up_test_data">Mondrian’s
+installation instructions</a>.)</p>
+
+<p><b>Current limitations</b>: The JDBC adapter currently only pushes
+down table scan operations; all other processing (filtering, joins,
+aggregations and so forth) occurs within Calcite. Our goal is to push
+down as much processing as possible to the source system, translating
+syntax, data types and built-in functions as we go. If a Calcite query
+is based on tables from a single JDBC database, in principle the whole
+query should go to that database. If tables are from multiple JDBC
+sources, or a mixture of JDBC and non-JDBC, Calcite will use the most
+efficient distributed query approach that it can.</p>
+
+<h2 id="the-cloning-jdbc-adapter">The cloning JDBC adapter</h2>
+
+<p>The cloning JDBC adapter creates a hybrid database. The data is
+sourced from a JDBC database but is read into in-memory tables the
+first time each table is accessed. Calcite evaluates queries based on
+those in-memory tables, effectively a cache of the database.</p>
+
+<p>For example, the following model reads tables from a MySQL
+“foodmart” database:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  defaultSchema: 'FOODMART_CLONE',
+  schemas: [
+    {
+      name: 'FOODMART_CLONE',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
+      operand: {
+        jdbcDriver: 'com.mysql.jdbc.Driver',
+        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
+        jdbcUser: 'foodmart',
+        jdbcPassword: 'foodmart'
+      }
+    }
+  ]
+}
+</code></p>
+
+<p>Another technique is to build a clone schema on top of an existing
+schema. You use the <code>source</code> property to reference a schema
+defined earlier in the model, like this:</p>
+
+<p><code>json
+{
+  version: '1.0',
+  defaultSchema: 'FOODMART_CLONE',
+  schemas: [
+    {
+      name: 'FOODMART',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.jdbc.JdbcSchema$Factory',
+      operand: {
+        jdbcDriver: 'com.mysql.jdbc.Driver',
+        jdbcUrl: 'jdbc:mysql://localhost/foodmart',
+        jdbcUser: 'foodmart',
+        jdbcPassword: 'foodmart'
+      }
+    },
+    {
+      name: 'FOODMART_CLONE',
+      type: 'custom',
+      factory: 'org.apache.calcite.adapter.clone.CloneSchema$Factory',
+      operand: {
+        source: 'FOODMART'
+      }
+    }
+  ]
+}
+</code></p>
+
+<p>You can use this approach to create a clone schema on any type of
+schema, not just JDBC.</p>
+
+<p>The cloning adapter isn’t the be-all and end-all. We plan to develop
+more sophisticated caching strategies, and a more complete and
+efficient implementation of in-memory tables, but for now the cloning
+JDBC adapter shows what is possible and allows us to try out our
+initial implementations.</p>
+
+<h2 id="further-topics">Further topics</h2>
+
+<h3 id="defining-a-custom-schema">Defining a custom schema</h3>
+
+<p>(To be written.)</p>
+
+<h3 id="modifying-data">Modifying data</h3>
+
+<p>How to enable DML operations (INSERT, UPDATE and DELETE) on your schema.</p>
+
+<p>(To be written.)</p>
+
+<h3 id="calling-conventions">Calling conventions</h3>
+
+<p>(To be written.)</p>
+
+<h3 id="statistics-and-cost">Statistics and cost</h3>
+
+<p>(To be written.)</p>
+
+<h3 id="defining-and-using-user-defined-functions">Defining and using user-defined functions</h3>
+
+<p>(To be written.)</p>
+
+<h3 id="defining-tables-in-a-schema">Defining tables in a schema</h3>
+
+<p>(To be written.)</p>
+
+<h3 id="defining-custom-tables">Defining custom tables</h3>
+
+<p>(To be written.)</p>
+
+<h3 id="built-in-sql-implementation">Built-in SQL implementation</h3>
+
+<p>How does Calcite implement SQL, if an adapter does not implement all of the core
+relational operators?</p>
+
+<p>(To be written.)</p>
+
+<h3 id="table-functions">Table functions</h3>
+
+<p>(To be written.)</p>
+
+<h2 id="further-resources">Further resources</h2>
+
+<ul>
+  <li><a href="http://calcite.incubator.apache.org">Apache Calcite</a> home
+page</li>
+</ul>
+
+          
+
+
+
+
+
+  
+  
+
+  
+  
+    <div class="section-nav">
+      <div class="left align-right">
+          
+            
+            
+            <a href="/docs/index.html" class="prev">Back</a>
+          
+      </div>
+      <div class="right align-left">
+          
+            
+            
+            <a href="/docs/algebra.html" class="next">Next</a>
+          
+      </div>
+    </div>
+    <div class="clear"></div>
+    
+
+        </article>
+      </div>
+
+      <div class="unit one-fifth hide-on-mobiles">
+  <aside>
+    
+    <h4>Overview</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/index.html">Background</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class="current"><a href="/docs/tutorial.html">Tutorial</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+      <li class=""><a href="/docs/algebra.html">Algebra</a></li>
+      
+
+
+</ul>
+
+    
+    <h4>Advanced</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+      <li class=""><a href="/docs/adapter.html">Adapters</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/avatica.html">Avatica</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/stream.html">Streaming</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/lattice.html">Lattices</a></li>
+      
+
+
+</ul>
+
+    
+    <h4>Reference</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/reference.html">SQL language</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/model.html">JSON models</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/howto.html">HOWTO</a></li>
+      
+
+
+</ul>
+
+    
+    <h4>Meta</h4>
+    
+
+<ul>
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/downloads.html">Downloads</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/history.html">History</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/contributing.html">Contributing</a></li>
+      
+
+
+  
+
+  
+    
+  
+
+  
+    
+  
+    
+  
+    
+      <li class=""><a href="/docs/api.html">API</a></li>
+      
+
+
+</ul>
+
+    
+  </aside>
+</div>
+
+
+      <div class="clear"></div>
+
+    </div>
+  </section>
+
+
+  <footer role="contentinfo">
+  <p>The contents of this website are &copy;&nbsp;2015
+     <a href="https://www.apache.org/">Apache Software Foundation</a>
+     under the terms of
+     the <a href="https://www.apache.org/licenses/LICENSE-2.0.html">
+     Apache&nbsp;License&nbsp;v2</a>. Apache Calcite and its logo are
+     trademarks of the Apache Software Foundation.</p>
+
+  <p>Apache Calcite is an effort undergoing incubation at The Apache
+      Software Foundation (ASF), sponsored by the Apache
+      Incubator. Incubation is required of all newly accepted projects
+      until a further review indicates that the infrastructure,
+      communications, and decision making process have stabilized in a
+      manner consistent with other successful ASF projects. While
+      incubation status is not necessarily a reflection of the
+      completeness or stability of the code, it does indicate that the
+      project has yet to be fully endorsed by the ASF.</p>
+  
+</footer>
+
+  <script>
+  var anchorForId = function (id) {
+    var anchor = document.createElement("a");
+    anchor.className = "header-link";
+    anchor.href      = "#" + id;
+    anchor.innerHTML = "<span class=\"sr-only\">Permalink</span><i class=\"fa fa-link\"></i>";
+    anchor.title = "Permalink";
+    return anchor;
+  };
+
+  var linkifyAnchors = function (level, containingElement) {
+    var headers = containingElement.getElementsByTagName("h" + level);
+    for (var h = 0; h < headers.length; h++) {
+      var header = headers[h];
+
+      if (typeof header.id !== "undefined" && header.id !== "") {
+        header.appendChild(anchorForId(header.id));
+      }
+    }
+  };
+
+  document.onreadystatechange = function () {
+    if (this.readyState === "complete") {
+      var contentBlock = document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
+      if (!contentBlock) {
+        return;
+      }
+      for (var level = 1; level <= 6; level++) {
+        linkifyAnchors(level, contentBlock);
+      }
+    }
+  };
+</script>
+
+
+</body>
+</html>

Added: incubator/calcite/site/downloads/index.html
URL: http://svn.apache.org/viewvc/incubator/calcite/site/downloads/index.html?rev=1682430&view=auto
==============================================================================
--- incubator/calcite/site/downloads/index.html (added)
+++ incubator/calcite/site/downloads/index.html Fri May 29 11:48:34 2015
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <title>Downloads</title>
+  <meta name="viewport" content="width=device-width,initial-scale=1">
+  <meta name="generator" content="Jekyll v2.4.0">
+  <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Lato:300,300italic,400,400italic,700,700italic,900">
+  <link rel="stylesheet" href="/css/screen.css">
+  <link rel="icon" type="image/x-icon" href="/favicon.ico">
+  <!--[if lt IE 9]>
+  <script src="/js/html5shiv.min.js"></script>
+  <script src="/js/respond.min.js"></script>
+  <![endif]-->
+</head>
+
+
+<body class="wrap">
+  <header role="banner">
+  <nav class="mobile-nav show-on-mobiles">
+    <ul>
+  <li class="">
+    <a href="/">Home</a>
+  </li>
+  <li class="">
+    <a href="/docs/">Documentation</a>
+  </li>
+  <li class="">
+    <a href="/talks/">Talks</a>
+  </li>
+  <li class="">
+    <a href="/news/">News</a>
+  </li>
+  <li class="">
+    <a href="/help/">Help</a>
+  </li>
+  <li class="">
+    <a href="/develop/">Develop</a>
+  </li>
+</ul>
+
+  </nav>
+  <div class="grid">
+    <div class="unit one-third center-on-mobiles">
+      <h1>
+        <a href="/">
+          <span class="sr-only">Apache Calcite</span>
+          <img src="/img/logo.png" width="226" height="140" alt="Calcite Logo">
+        </a>
+      </h1>
+    </div>
+    <nav class="main-nav unit two-thirds hide-on-mobiles">
+      <ul>
+  <li class="">
+    <a href="/">Home</a>
+  </li>
+  <li class="">
+    <a href="/docs/">Documentation</a>
+  </li>
+  <li class="">
+    <a href="/talks/">Talks</a>
+  </li>
+  <li class="">
+    <a href="/news/">News</a>
+  </li>
+  <li class="">
+    <a href="/help/">Help</a>
+  </li>
+  <li class="">
+    <a href="/develop/">Develop</a>
+  </li>
+</ul>
+
+    </nav>
+  </div>
+</header>
+
+
+  <section class="standalone">
+  <div class="grid">
+
+    <div class="unit whole">
+      <article>
+        <h1>Downloads</h1>
+        <p>We haven’t made any releases as a separate project yet. Please download
+the Hive 1.1 release and use the hive-exec.jar.</p>
+
+      </article>
+    </div>
+
+    <div class="clear"></div>
+
+  </div>
+</section>
+
+
+  <footer role="contentinfo">
+  <p>The contents of this website are &copy;&nbsp;2015
+     <a href="https://www.apache.org/">Apache Software Foundation</a>
+     under the terms of
+     the <a href="https://www.apache.org/licenses/LICENSE-2.0.html">
+     Apache&nbsp;License&nbsp;v2</a>. Apache Calcite and its logo are
+     trademarks of the Apache Software Foundation.</p>
+
+  <p>Apache Calcite is an effort undergoing incubation at The Apache
+      Software Foundation (ASF), sponsored by the Apache
+      Incubator. Incubation is required of all newly accepted projects
+      until a further review indicates that the infrastructure,
+      communications, and decision making process have stabilized in a
+      manner consistent with other successful ASF projects. While
+      incubation status is not necessarily a reflection of the
+      completeness or stability of the code, it does indicate that the
+      project has yet to be fully endorsed by the ASF.</p>
+  
+</footer>
+
+  <script>
+  var anchorForId = function (id) {
+    var anchor = document.createElement("a");
+    anchor.className = "header-link";
+    anchor.href      = "#" + id;
+    anchor.innerHTML = "<span class=\"sr-only\">Permalink</span><i class=\"fa fa-link\"></i>";
+    anchor.title = "Permalink";
+    return anchor;
+  };
+
+  var linkifyAnchors = function (level, containingElement) {
+    var headers = containingElement.getElementsByTagName("h" + level);
+    for (var h = 0; h < headers.length; h++) {
+      var header = headers[h];
+
+      if (typeof header.id !== "undefined" && header.id !== "") {
+        header.appendChild(anchorForId(header.id));
+      }
+    }
+  };
+
+  document.onreadystatechange = function () {
+    if (this.readyState === "complete") {
+      var contentBlock = document.getElementsByClassName("docs")[0] || document.getElementsByClassName("news")[0];
+      if (!contentBlock) {
+        return;
+      }
+      for (var level = 1; level <= 6; level++) {
+        linkifyAnchors(level, contentBlock);
+      }
+    }
+  };
+</script>
+
+
+</body>
+</html>

Added: incubator/calcite/site/favicon.ico
URL: http://svn.apache.org/viewvc/incubator/calcite/site/favicon.ico?rev=1682430&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/calcite/site/favicon.ico
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/calcite/site/fonts/fontawesome-webfont.eot
URL: http://svn.apache.org/viewvc/incubator/calcite/site/fonts/fontawesome-webfont.eot?rev=1682430&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/calcite/site/fonts/fontawesome-webfont.eot
------------------------------------------------------------------------------
    svn:executable = *

Propchange: incubator/calcite/site/fonts/fontawesome-webfont.eot
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream