This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-datafusion.git


The following commit(s) were added to refs/heads/main by this push:
     new 3da9192d2a Add library guide for table provider and catalog providers 
(#7287)
3da9192d2a is described below

commit 3da9192d2a6ba95ed2c435fba46bbf5a8cb86b1a
Author: Trent Hauck <[email protected]>
AuthorDate: Wed Aug 16 06:28:48 2023 -0700

    Add library guide for table provider and catalog providers (#7287)
    
    * docs: add user guide
    
    * docs: fill out skeleton
    
    * docs: add toc
    
    * docs: fix warning
    
    * docs: run prettier
    
    * docs: fix bad text
    
    * docs: re-order sidebar
    
    * Update docs/source/library-user-guide/catalogs.md
    
    Co-authored-by: Andrew Lamb <[email protected]>
    
    * Update docs/source/library-user-guide/catalogs.md
    
    Co-authored-by: Andrew Lamb <[email protected]>
    
    * Update docs/source/library-user-guide/catalogs.md
    
    Co-authored-by: Andrew Lamb <[email protected]>
    
    * Apply suggestions from code review
    
    Co-authored-by: Andrew Lamb <[email protected]>
    
    * docs: run prettier
    
    * docs: update e plan docs
    
    ---------
    
    Co-authored-by: Andrew Lamb <[email protected]>
---
 datafusion-examples/examples/catalog.rs            |   2 +-
 docs/source/index.rst                              |  17 ++
 docs/source/library-user-guide/adding-udfs.md      |  22 +++
 .../library-user-guide/building-logical-plans.md   |  22 +++
 docs/source/library-user-guide/catalogs.md         | 179 +++++++++++++++++++++
 .../library-user-guide/custom-table-providers.md   | 161 ++++++++++++++++++
 docs/source/library-user-guide/execution-plans.md  |  22 +++
 .../library-user-guide/extending-operators.md      |  22 +++
 docs/source/library-user-guide/index.md            |  26 +++
 .../library-user-guide/using-the-dataframe-api.md  |  22 +++
 .../source/library-user-guide/using-the-sql-api.md |  22 +++
 .../library-user-guide/working-with-exprs.md       |  22 +++
 12 files changed, 538 insertions(+), 1 deletion(-)

diff --git a/datafusion-examples/examples/catalog.rs 
b/datafusion-examples/examples/catalog.rs
index 5ae510aab2..aa9fd103a5 100644
--- a/datafusion-examples/examples/catalog.rs
+++ b/datafusion-examples/examples/catalog.rs
@@ -58,7 +58,7 @@ async fn main() -> Result<()> {
     // context will by default have MemoryCatalogList
     ctx.register_catalog_list(catlist.clone());
 
-    // intitialize our catalog and schemas
+    // initialize our catalog and schemas
     let catalog = DirCatalog::new();
     let parquet_schema = DirSchema::create(
         &state,
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 4f45771173..acc17ebeff 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -63,6 +63,23 @@ The `developer’s guide`_ contains information on how to 
contribute.
    user-guide/configs
    user-guide/faq
 
+.. _toc.library-user-guide:
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Library User Guide
+
+   library-user-guide/index
+   library-user-guide/using-the-sql-api
+   library-user-guide/working-with-exprs
+   library-user-guide/using-the-dataframe-api
+   library-user-guide/building-logical-plans
+   library-user-guide/catalogs
+   library-user-guide/adding-udfs
+   library-user-guide/custom-table-providers
+   library-user-guide/extending-operators
+   library-user-guide/execution-plans
+
 .. _toc.contributor-guide:
 
 .. toctree::
diff --git a/docs/source/library-user-guide/adding-udfs.md 
b/docs/source/library-user-guide/adding-udfs.md
new file mode 100644
index 0000000000..45d5afc1f0
--- /dev/null
+++ b/docs/source/library-user-guide/adding-udfs.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Adding User Defined Functions: Scalar/Window/Aggregate
+
+Coming Soon
diff --git a/docs/source/library-user-guide/building-logical-plans.md 
b/docs/source/library-user-guide/building-logical-plans.md
new file mode 100644
index 0000000000..406f488112
--- /dev/null
+++ b/docs/source/library-user-guide/building-logical-plans.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Building Logical Plans
+
+Coming Soon
diff --git a/docs/source/library-user-guide/catalogs.md 
b/docs/source/library-user-guide/catalogs.md
new file mode 100644
index 0000000000..226e283324
--- /dev/null
+++ b/docs/source/library-user-guide/catalogs.md
@@ -0,0 +1,179 @@
+<!---
+  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.
+-->
+
+# Catalogs, Schemas, and Tables
+
+This section describes how to create and manage catalogs, schemas, and tables 
in DataFusion. For those wanting to dive into the code quickly please see the 
[example](../../../datafusion-examples/examples/catalog.rs).
+
+## General Concepts
+
+Catalogs, schemas, and tables are organized in a hierarchy. A catalog contains 
schemas, and a schema contains tables.
+
+DataFusion comes with a basic in memory catalog functionality in the 
[`catalog` module]. You can use these in memory implementations as is, or 
extend DataFusion with your own catalog implementations, for example based on 
local files or files on remote object storage.
+
+[`catalog` module]: 
https://docs.rs/datafusion/latest/datafusion/catalog/index.html
+
+Similarly to other concepts in DataFusion, you'll implement various traits to 
create your own catalogs, schemas, and tables. The following sections describe 
the traits you'll need to implement.
+
+The `CatalogProvider` trait has methods to set a schema to a name, get a 
schema by name, and list all schemas. The `SchemaProvider`, which can be 
registered with a `CatalogProvider`, has methods to set a table to a name, get 
a table by name, list all tables, deregister a table, and check for a table's 
existence. The `TableProvider` trait has methods to scan underlying data and 
use it in DataFusion. The `TableProvider` trait is covered in more detail 
[here](./custom-table-providers.md).
+
+In the following example, we'll implement an in memory catalog, starting with 
the `SchemaProvider` trait as we need one to register with the 
`CatalogProvider`.
+
+## Implementing `MemorySchemaProvider`
+
+The `MemorySchemaProvider` is a simple implementation of the `SchemaProvider` 
trait. It stores state (i.e. tables) in a `DashMap`, which then underlies the 
`SchemaProvider` trait.
+
+```rust
+pub struct MemorySchemaProvider {
+    tables: DashMap<String, Arc<dyn TableProvider>>,
+}
+```
+
+`tables` is the key-value pair described above. The underlying state could 
also be another data structure or other storage mechanism such as a file or 
transactional database.
+
+Then we implement the `SchemaProvider` trait for `MemorySchemaProvider`.
+
+```rust
+#[async_trait]
+impl SchemaProvider for MemorySchemaProvider {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn table_names(&self) -> Vec<String> {
+        self.tables
+            .iter()
+            .map(|table| table.key().clone())
+            .collect()
+    }
+
+    async fn table(&self, name: &str) -> Option<Arc<dyn TableProvider>> {
+        self.tables.get(name).map(|table| table.value().clone())
+    }
+
+    fn register_table(
+        &self,
+        name: String,
+        table: Arc<dyn TableProvider>,
+    ) -> Result<Option<Arc<dyn TableProvider>>> {
+        if self.table_exist(name.as_str()) {
+            return Err(DataFusionError::Execution(format!(
+                "The table {name} already exists"
+            )));
+        }
+        Ok(self.tables.insert(name, table))
+    }
+
+    fn deregister_table(&self, name: &str) -> Result<Option<Arc<dyn 
TableProvider>>> {
+        Ok(self.tables.remove(name).map(|(_, table)| table))
+    }
+
+    fn table_exist(&self, name: &str) -> bool {
+        self.tables.contains_key(name)
+    }
+}
+```
+
+Without getting into a `CatalogProvider` implementation, we can create a 
`MemorySchemaProvider` and register `TableProvider`s with it.
+
+```rust
+let schema_provider = Arc::new(MemorySchemaProvider::new());
+let table_provider = _; // create a table provider
+
+schema_provider.register_table("table_name".to_string(), table_provider);
+
+let table = schema_provider.table("table_name").unwrap();
+```
+
+### Asynchronous `SchemaProvider`
+
+It's often useful to fetch metadata about which tables are in a schema, from a 
remote source. For example, a schema provider could fetch metadata from a 
remote database. To support this, the `SchemaProvider` trait has an 
asynchronous `table` method.
+
+The trait is roughly the same except for the `table` method, and the addition 
of the `#[async_trait]` attribute.
+
+```rust
+#[async_trait]
+impl SchemaProvider for Schema {
+    async fn table(&self, name: &str) -> Option<Arc<dyn TableProvider>> {
+        // fetch metadata from remote source
+    }
+}
+```
+
+### Implementing `MemoryCatalogProvider`
+
+As mentioned, the `CatalogProvider` can manage the schemas in a catalog, and 
the `MemoryCatalogProvider` is a simple implementation of the `CatalogProvider` 
trait. It stores schemas in a `DashMap`.
+
+```rust
+pub struct MemoryCatalogList {
+    /// Collection of catalogs containing schemas and ultimately TableProviders
+    pub catalogs: DashMap<String, Arc<dyn CatalogProvider>>,
+}
+```
+
+With that the `CatalogProvider` trait can be implemented.
+
+```rust
+impl CatalogProvider for MemoryCatalogProvider {
+    fn as_any(&self) -> &dyn Any {
+        self
+    }
+
+    fn schema_names(&self) -> Vec<String> {
+        self.schemas.iter().map(|s| s.key().clone()).collect()
+    }
+
+    fn schema(&self, name: &str) -> Option<Arc<dyn SchemaProvider>> {
+        self.schemas.get(name).map(|s| s.value().clone())
+    }
+
+    fn register_schema(
+        &self,
+        name: &str,
+        schema: Arc<dyn SchemaProvider>,
+    ) -> Result<Option<Arc<dyn SchemaProvider>>> {
+        Ok(self.schemas.insert(name.into(), schema))
+    }
+
+    fn deregister_schema(
+        &self,
+        name: &str,
+        cascade: bool,
+    ) -> Result<Option<Arc<dyn SchemaProvider>>> {
+        /// `cascade` is not used here, but can be used to control whether
+        /// to delete all tables in the schema or not.
+        if let Some(schema) = self.schema(name) {
+            let (_, removed) = self.schemas.remove(name).unwrap();
+            Ok(Some(removed))
+        } else {
+            Ok(None)
+        }
+    }
+}
+```
+
+Again, this is fairly straightforward, as there's an underlying data structure 
to store the state, via key-value pairs.
+
+## Recap
+
+To recap, you need to:
+
+1. Implement the `TableProvider` trait to create a table provider, or use an 
existing one.
+2. Implement the `SchemaProvider` trait to create a schema provider, or use an 
existing one.
+3. Implement the `CatalogProvider` trait to create a catalog provider, or use 
an existing one.
diff --git a/docs/source/library-user-guide/custom-table-providers.md 
b/docs/source/library-user-guide/custom-table-providers.md
new file mode 100644
index 0000000000..30721d6a5b
--- /dev/null
+++ b/docs/source/library-user-guide/custom-table-providers.md
@@ -0,0 +1,161 @@
+<!---
+  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.
+-->
+
+# Custom Table Provider
+
+Like other areas of DataFusion, you extend DataFusion's functionality by 
implementing a trait. The `TableProvider` and associated traits, have methods 
that allow you to implement a custom table provider, i.e. use DataFusion's 
other functionality with your custom data source.
+
+This section will also touch on how to have DataFusion use the new 
`TableProvider` implementation.
+
+## Table Provider and Scan
+
+The `scan` method on the `TableProvider` is likely its most important. It 
returns an `ExecutionPlan` that DataFusion will use to read the actual data 
during execution o the query.
+
+### Scan
+
+As mentioned, `scan` returns an execution plan, and in particular a 
`Result<Arc<dyn ExecutionPlan>>`. The core of this is returning something that 
can be dynamically dispatched to an `ExecutionPlan`. And as per the general 
DataFusion idea, we'll need to implement it.
+
+#### Execution Plan
+
+The `ExecutionPlan` trait at its core is a way to get a stream of batches. The 
aptly-named `execute` method returns a `Result<SendableRecordBatchStream>`, 
which should be a stream of `RecordBatch`es that can be sent across threads, 
and has a schema that matches the data to be contained in those batches.
+
+There are many different types of `SendableRecordBatchStream` implemented in 
DataFusion -- you can use a pre existing one, such as `MemoryStream` (if your 
`RecordBatch`es are all in memory) or implement your own custom logic, 
depending on your usecase.
+
+Looking at the [example in this repo][ex], the execute method:
+
+```rust
+struct CustomExec {
+    db: CustomDataSource,
+    projected_schema: SchemaRef,
+}
+
+impl ExecutionPlan for CustomExec {
+    fn execute(
+        &self,
+        _partition: usize,
+        _context: Arc<TaskContext>,
+    ) -> Result<SendableRecordBatchStream> {
+        let users: Vec<User> = {
+            let db = self.db.inner.lock().unwrap();
+            db.data.values().cloned().collect()
+        };
+
+        let mut id_array = UInt8Builder::with_capacity(users.len());
+        let mut account_array = UInt64Builder::with_capacity(users.len());
+
+        for user in users {
+            id_array.append_value(user.id);
+            account_array.append_value(user.bank_account);
+        }
+
+        Ok(Box::pin(MemoryStream::try_new(
+            vec![RecordBatch::try_new(
+                self.projected_schema.clone(),
+                vec![
+                    Arc::new(id_array.finish()),
+                    Arc::new(account_array.finish()),
+                ],
+            )?],
+            self.schema(),
+            None,
+        )?))
+    }
+}
+```
+
+This:
+
+1. Gets the users from the database
+2. Constructs the individual output arrays (columns)
+3. Returns a `MemoryStream` of a single `RecordBatch` with the arrays
+
+I.e. returns the "physical" data. For other examples, refer to the 
[`CsvExec`][csv] and [`ParquetExec`][parquet] for more complex implementations.
+
+With the `ExecutionPlan` implemented, we can now implement the `scan` method 
of the `TableProvider`.
+
+#### Scan Revisited
+
+The `scan` method of the `TableProvider` returns a `Result<Arc<dyn 
ExecutionPlan>>`. We can use the `Arc` to return a reference-counted pointer to 
the `ExecutionPlan` we implemented. In the example, this is done by:
+
+```rust
+impl CustomDataSource {
+    pub(crate) async fn create_physical_plan(
+        &self,
+        projections: Option<&Vec<usize>>,
+        schema: SchemaRef,
+    ) -> Result<Arc<dyn ExecutionPlan>> {
+        Ok(Arc::new(CustomExec::new(projections, schema, self.clone())))
+    }
+}
+
+#[async_trait]
+impl TableProvider for CustomDataSource {
+    async fn scan(
+        &self,
+        _state: &SessionState,
+        projection: Option<&Vec<usize>>,
+        // filters and limit can be used here to inject some push-down 
operations if needed
+        _filters: &[Expr],
+        _limit: Option<usize>,
+    ) -> Result<Arc<dyn ExecutionPlan>> {
+        return self.create_physical_plan(projection, self.schema()).await;
+    }
+}
+```
+
+With this, and the implementation of the omitted methods, we can now use the 
`CustomDataSource` as a `TableProvider` in DataFusion.
+
+## Using the Custom Table Provider
+
+In order to use the custom table provider, we need to register it with 
DataFusion. This is done by creating a `TableProvider` and registering it with 
the `ExecutionContext`.
+
+```rust
+let mut ctx = ExecutionContext::new();
+
+let custom_table_provider = CustomDataSource::new();
+ctx.register_table("custom_table", Arc::new(custom_table_provider));
+```
+
+This will allow you to use the custom table provider in DataFusion. For 
example, you could use it in a SQL query to get a `DataFrame`.
+
+```rust
+let df = ctx.sql("SELECT id, bank_account FROM custom_table")?;
+```
+
+## Recap
+
+To recap, in order to implement a custom table provider, you need to:
+
+1. Implement the `TableProvider` trait
+2. Implement the `ExecutionPlan` trait
+3. Register the `TableProvider` with the `ExecutionContext`
+
+## Next Steps
+
+As mentioned the [csv] and [parquet] implementations are good examples of how 
to implement a `TableProvider`. The [example in this repo][ex] is a good 
example of how to implement a `TableProvider` that uses a custom data source.
+
+More abstractly, see the following traits for more information on how to 
implement a custom `TableProvider` for a file format:
+
+- `FileOpener` - a trait for opening a file and inferring the schema
+- `FileFormat` - a trait for reading a file format
+- `ListingTableProvider` - a useful trait for implementing a `TableProvider` 
that lists files in a directory
+
+[ex]: 
https://github.com/apache/arrow-datafusion/blob/a5e86fae3baadbd99f8fd0df83f45fde22f7b0c6/datafusion-examples/examples/custom_datasource.rs#L214C1-L276
+[csv]: 
https://github.com/apache/arrow-datafusion/blob/a5e86fae3baadbd99f8fd0df83f45fde22f7b0c6/datafusion/core/src/datasource/physical_plan/csv.rs#L57-L70
+[parquet]: 
https://github.com/apache/arrow-datafusion/blob/a5e86fae3baadbd99f8fd0df83f45fde22f7b0c6/datafusion/core/src/datasource/physical_plan/parquet.rs#L77-L104
diff --git a/docs/source/library-user-guide/execution-plans.md 
b/docs/source/library-user-guide/execution-plans.md
new file mode 100644
index 0000000000..5169151685
--- /dev/null
+++ b/docs/source/library-user-guide/execution-plans.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Execution Plans
+
+More information will be added here soon, but for now, see the [Custom Table 
Provider](./custom-table-providers.md) documentation for an example 
implementation.
diff --git a/docs/source/library-user-guide/extending-operators.md 
b/docs/source/library-user-guide/extending-operators.md
new file mode 100644
index 0000000000..631bdc6797
--- /dev/null
+++ b/docs/source/library-user-guide/extending-operators.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Extending DataFusion's operators: custom LogicalPlan and Execution Plans
+
+Coming soon
diff --git a/docs/source/library-user-guide/index.md 
b/docs/source/library-user-guide/index.md
new file mode 100644
index 0000000000..47257e0c92
--- /dev/null
+++ b/docs/source/library-user-guide/index.md
@@ -0,0 +1,26 @@
+<!---
+  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.
+-->
+
+# Introduction
+
+The library user guide explains how to use the DataFusion library as a 
dependency in your Rust project. Please check out the user-guide for more 
details on how to use DataFusion's SQL and DataFrame APIs, or the contributor 
guide for details on how to contribute to DataFusion.
+
+If you haven't reviewed the [architecture section in the docs][docs], it's a 
useful place to get the lay of the land before starting down a specific path.
+
+[docs]: https://docs.rs/datafusion/latest/datafusion/#architecture
diff --git a/docs/source/library-user-guide/using-the-dataframe-api.md 
b/docs/source/library-user-guide/using-the-dataframe-api.md
new file mode 100644
index 0000000000..fdf309980d
--- /dev/null
+++ b/docs/source/library-user-guide/using-the-dataframe-api.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Using the DataFrame API
+
+Coming Soon
diff --git a/docs/source/library-user-guide/using-the-sql-api.md 
b/docs/source/library-user-guide/using-the-sql-api.md
new file mode 100644
index 0000000000..f4e85ee4e3
--- /dev/null
+++ b/docs/source/library-user-guide/using-the-sql-api.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Using the SQL API
+
+Coming Soon
diff --git a/docs/source/library-user-guide/working-with-exprs.md 
b/docs/source/library-user-guide/working-with-exprs.md
new file mode 100644
index 0000000000..b1a26cdfcb
--- /dev/null
+++ b/docs/source/library-user-guide/working-with-exprs.md
@@ -0,0 +1,22 @@
+<!---
+  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.
+-->
+
+# Working with Exprs
+
+Coming Soon

Reply via email to