You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sedona.apache.org by gi...@apache.org on 2025/12/12 16:11:44 UTC
(sedona-db) branch asf-site updated: Deployed ce85315 to latest-snapshot with MkDocs 1.6.1 and mike 2.1.3
This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/sedona-db.git
The following commit(s) were added to refs/heads/asf-site by this push:
new e3793a78 Deployed ce85315 to latest-snapshot with MkDocs 1.6.1 and mike 2.1.3
e3793a78 is described below
commit e3793a7870cb3868687ad08c70d37b9918d0deb4
Author: GitHub Actions <ac...@github.com>
AuthorDate: Fri Dec 12 16:11:39 2025 +0000
Deployed ce85315 to latest-snapshot with MkDocs 1.6.1 and mike 2.1.3
---
latest-snapshot/contributors-guide/index.html | 67 ++++++-
.../_matplotlib_defaults.cpython-314.pyc | Bin 0 -> 431 bytes
.../_extensions/function-listing/_extension.yml} | 19 +-
.../function-listing/function-listing.lua | 43 +++++
.../_extensions/render-meta-and-examples.lua | 137 +++++++++++++
.../functions/_matplotlib_defaults.py} | 17 +-
latest-snapshot/reference/functions/_quarto.yml | 46 +++++
.../reference/functions/_render_examples.py | 120 ++++++++++++
.../reference/functions/_render_listing.py | 83 ++++++++
.../reference/functions/_render_meta.py | 213 +++++++++++++++++++++
.../functions/index.qmd} | 17 +-
.../reference/functions/st_analyze_agg.qmd | 49 +++++
latest-snapshot/reference/functions/st_buffer.qmd | 81 ++++++++
.../reference/functions/st_intersection.qmd | 54 ++++++
latest-snapshot/requirements.txt | 1 +
latest-snapshot/search/search_index.json | 2 +-
16 files changed, 911 insertions(+), 38 deletions(-)
diff --git a/latest-snapshot/contributors-guide/index.html b/latest-snapshot/contributors-guide/index.html
index 7bad34ad..ce822c01 100644
--- a/latest-snapshot/contributors-guide/index.html
+++ b/latest-snapshot/contributors-guide/index.html
@@ -2046,6 +2046,71 @@ cargo<span class="w"> </span>bench
</li>
<li>Push your changes and open a pull request.</li>
</ol>
+<p>SQL function reference is special: because we provide so many functions, we have
+a specialized syntax for documenting them. The minimum required documentation for
+a function is a file <code>docs/reference/functions/function_name.qmd</code>:</p>
+<div class="codehilite"><pre><span></span><code><span class="c1">---</span>
+<span class="nl">title</span><span class="p">:</span><span class="w"> </span><span class="n">ST_FunctionName</span>
+<span class="nl">description</span><span class="p">:</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">brief</span><span class="w"> </span><span class="n">one</span><span class="w"> </span><span class="n">sentence</span><span class="w"> </span><span class="n">description</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="n">what</span><span class="w"> </span><span class="n">the</span><span class="w"> </s [...]
+<span class="nl">kernels</span><span class="p">:</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="k">returns</span><span class="err">:</span><span class="w"> </span><span class="n">geometry</span>
+<span class="w"> </span><span class="nl">args</span><span class="p">:</span><span class="w"> </span><span class="o">[</span><span class="n">geometry</span><span class="o">]</span>
+<span class="c1">---</span>
+
+<span class="err">##</span><span class="w"> </span><span class="n">Examples</span>
+
+<span class="err">```</span><span class="k">sql</span>
+<span class="k">SELECT</span><span class="w"> </span><span class="n">ST_FunctionName</span><span class="p">(</span><span class="n">ST_Point</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="p">))</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">val</span><span class="p">;</span>
+<span class="err">```</span>
+</code></pre></div>
+
+<p>After writing this file, the <code>.md</code> file may be rendered using <a href="https://quarto.org">Quarto</a>:</p>
+<div class="highlight"><pre><span></span><code><span class="nb">cd</span><span class="w"> </span>docs/reference/functions
+quarto<span class="w"> </span>render
+</code></pre></div>
+<p>This command (1) expands <code>description</code> and <code>kernels</code> to a templated representation,
+(2) checks and renders the result of the SQL examples, and (3) executes any
+<a href="https://quarto.org/docs/computations/python.html">Python code chunks</a>. These may
+be used to render figures that demonstrate visually what a function does or how its
+parameters affect the result.</p>
+<p>The <code>kernels</code> section of the frontmatter allows multiple implementations of a function
+to be documented. For example, many functions include implementations for geometry
+<em>and</em> geography or allow extra arguments to be supplied to customize behaviour. As
+an example, the frontmatter for <code>ST_Buffer()</code> is:</p>
+<div class="codehilite"><pre><span></span><code><span class="o">---</span>
+<span class="nx">title</span><span class="p">:</span><span class="w"> </span><span class="nx">ST_Buffer</span>
+<span class="nx">description</span><span class="p">:</span><span class="w"> </span><span class="p">></span>
+<span class="w"> </span><span class="nx">Computes</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">geometry</span><span class="w"> </span><span class="nx">that</span><span class="w"> </span><span class="nx">represents</span><span class="w"> </span><span class="nx">all</span><span class="w"> </span><span class="nx">points</span><span class="w"> </span><span class="nx">whose</span><span class="w"> </span><span class="nx">distance</span><spa [...]
+<span class="w"> </span><span class="nx">geometry</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="nx">less</span><span class="w"> </span><span class="nx">than</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="nx">equal</span><span class="w"> </span><span class="nx">to</span><span class="w"> </span><span class="nx">a</span><span class="w"> </span><span class="nx">specified</span><span class="w"> </spa [...]
+<span class="nx">kernels</span><span class="p">:</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">returns</span><span class="p">:</span><span class="w"> </span><span class="nx">geometry</span>
+<span class="w"> </span><span class="nx">args</span><span class="p">:</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">geometry</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">name</span><span class="p">:</span><span class="w"> </span><span class="nx">distance</span>
+<span class="w"> </span><span class="k">type</span><span class="p">:</span><span class="w"> </span><span class="nx">float64</span>
+<span class="w"> </span><span class="nx">description</span><span class="p">:</span><span class="w"> </span><span class="nx">Radius</span><span class="w"> </span><span class="nx">of</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">buffer</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">returns</span><span class="p">:</span><span class="w"> </span><span class="nx">geometry</span>
+<span class="w"> </span><span class="nx">args</span><span class="p">:</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">geometry</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">name</span><span class="p">:</span><span class="w"> </span><span class="nx">distance</span>
+<span class="w"> </span><span class="k">type</span><span class="p">:</span><span class="w"> </span><span class="nx">float64</span>
+<span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">name</span><span class="p">:</span><span class="w"> </span><span class="nx">params</span>
+<span class="w"> </span><span class="k">type</span><span class="p">:</span><span class="w"> </span><span class="nx">utf8</span>
+<span class="w"> </span><span class="nx">description</span><span class="p">:</span><span class="w"> </span><span class="nx">Space</span><span class="o">-</span><span class="nx">separated</span><span class="w"> </span><span class="err">`</span><span class="nx">key</span><span class="p">=</span><span class="nx">value</span><span class="err">`</span><span class="w"> </span><span class="nx">parameters</span><span class="p">.</span>
+<span class="o">---</span>
+</code></pre></div>
+
+<p>This illustrates a few ways in which arguments can be defined:</p>
+<ul>
+<li>By the string <code>geometry</code>, <code>geography</code>, or <code>raster</code>. These are expanded to a full
+ definition by quarto but are so common that we allow abbreviating them to avoid
+ typing <code>description: Input geometry</code> for every single function.</li>
+<li>With a YAML object of <code>name</code> / <code>type</code> / <code>description</code>. The type names are lowercase
+ Arrow type names which should be identical to those printed when executing a query
+ in SedonaDB.</li>
+</ul>
+<p>The build system for function documentation is a work in progress, so be sure to ask
+if you run into problems or have any questions about the syntax!</p>
@@ -2066,7 +2131,7 @@ cargo<span class="w"> </span>bench
<span class="md-icon" title="Last update">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"></path></svg>
</span>
- <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-datetime" title="November 9, 2025 03:42:23 UTC">November 9, 2025 03:42:23</span>
+ <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-datetime" title="December 12, 2025 16:07:28 UTC">December 12, 2025 16:07:28</span>
</span>
diff --git a/latest-snapshot/reference/functions/__pycache__/_matplotlib_defaults.cpython-314.pyc b/latest-snapshot/reference/functions/__pycache__/_matplotlib_defaults.cpython-314.pyc
new file mode 100644
index 00000000..1cb53d12
Binary files /dev/null and b/latest-snapshot/reference/functions/__pycache__/_matplotlib_defaults.cpython-314.pyc differ
diff --git a/latest-snapshot/requirements.txt b/latest-snapshot/reference/functions/_extensions/function-listing/_extension.yml
similarity index 82%
copy from latest-snapshot/requirements.txt
copy to latest-snapshot/reference/functions/_extensions/function-listing/_extension.yml
index 6bd80c39..a218f5f7 100644
--- a/latest-snapshot/requirements.txt
+++ b/latest-snapshot/reference/functions/_extensions/function-listing/_extension.yml
@@ -15,15 +15,10 @@
# specific language governing permissions and limitations
# under the License.
-griffe
-mike
-mkdocs
-mkdocs-git-revision-date-localized-plugin
-mkdocs-glightbox
-mkdocs-macros-plugin
-mkdocs-material
-mkdocstrings[python]
-nbconvert
-pyproj
-ruff
-lonboard
+title: Function Listing
+author: SedonaDB
+version: 1.0.0
+quarto-required: ">=1.4.0"
+contributes:
+ shortcodes:
+ - function-listing.lua
diff --git a/latest-snapshot/reference/functions/_extensions/function-listing/function-listing.lua b/latest-snapshot/reference/functions/_extensions/function-listing/function-listing.lua
new file mode 100644
index 00000000..460d1570
--- /dev/null
+++ b/latest-snapshot/reference/functions/_extensions/function-listing/function-listing.lua
@@ -0,0 +1,43 @@
+-- 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.
+
+return {
+ ["function-listing"] = function(args, kwargs, meta)
+ -- Get the file pattern from arguments (default to "st_*.qmd")
+ local file_pattern = args[1] or "st_*.qmd"
+
+ -- Execute _render_listing.py with the file pattern
+ local cmd = string.format("python3 _render_listing.py '%s'", file_pattern)
+ local handle = io.popen(cmd, "r")
+
+ if not handle then
+ return pandoc.Para{pandoc.Str("Error: Could not execute _render_listing.py")}
+ end
+
+ local result = handle:read("*all")
+ handle:close()
+
+ -- Parse the markdown result and return as pandoc blocks
+ if result and result ~= "" then
+ local doc_result = pandoc.read(result, "markdown")
+ return doc_result.blocks
+ end
+
+ -- Fallback if no result
+ return pandoc.Para{pandoc.Str("No functions found matching pattern: " .. file_pattern)}
+ end
+}
diff --git a/latest-snapshot/reference/functions/_extensions/render-meta-and-examples.lua b/latest-snapshot/reference/functions/_extensions/render-meta-and-examples.lua
new file mode 100644
index 00000000..51e1781f
--- /dev/null
+++ b/latest-snapshot/reference/functions/_extensions/render-meta-and-examples.lua
@@ -0,0 +1,137 @@
+-- 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.
+
+-- auto-description.lua
+-- Automatically adds a Description section based on frontmatter using _render_meta.py
+-- Also processes SQL code blocks using _render_examples.py
+
+local function render_sql_example(sql_code)
+ -- Create a temporary file for the SQL
+ local temp_file = os.tmpname()
+
+ -- Write SQL content to temporary file
+ local temp_handle = io.open(temp_file, "w")
+ if not temp_handle then
+ return {pandoc.CodeBlock(sql_code, pandoc.Attr("", {"sql"}, {}))}
+ end
+
+ temp_handle:write(sql_code)
+ temp_handle:close()
+
+ -- Execute _render_examples.py using stdin (with - argument)
+ local cmd = string.format("python3 _render_examples.py - < '%s'", temp_file)
+ local handle = io.popen(cmd, "r")
+ if not handle then
+ os.remove(temp_file)
+ return {pandoc.CodeBlock(sql_code, pandoc.Attr("", {"sql"}, {}))}
+ end
+
+ local result = handle:read("*all")
+ handle:close()
+ os.remove(temp_file)
+
+ -- Parse the markdown result and return as pandoc blocks
+ if result and result ~= "" then
+ local doc_result = pandoc.read(result, "markdown")
+ return doc_result.blocks
+ end
+
+ -- Fallback to original code block if rendering fails
+ return {pandoc.CodeBlock(sql_code, pandoc.Attr("", {"sql"}, {}))}
+end
+
+local function render_meta_content(doc)
+ -- Use Pandoc's JSON encoding (may not work perfectly)
+ local json_content = pandoc.json.encode(doc.meta)
+
+ -- Create a temporary file for the JSON
+ local temp_file = os.tmpname()
+
+ -- Write JSON content to temporary file
+ local temp_handle = io.open(temp_file, "w")
+ if not temp_handle then
+ return pandoc.Para{pandoc.Str("Error: Could not create temporary file")}
+ end
+
+ temp_handle:write(json_content)
+ temp_handle:close()
+
+ -- Pass JSON directly to _render_meta.py (JSON is valid YAML)
+ local cmd = string.format("python3 _render_meta.py - < '%s'", temp_file)
+
+ local handle = io.popen(cmd, "r")
+ if not handle then
+ os.remove(temp_file)
+ return pandoc.Para{pandoc.Str("Error: Could not execute _render_meta.py")}
+ end
+
+ local result = handle:read("*all")
+ if not result then
+ result = "Error: Could not read output from _render_meta.py"
+ end
+
+ handle:close()
+ os.remove(temp_file) -- Parse the markdown result and return as pandoc blocks
+ if result and result ~= "" then
+ local doc_result = pandoc.read(result, "markdown")
+ return doc_result.blocks
+ end
+
+ return {}
+end
+
+function Pandoc(doc)
+ local description = doc.meta.description
+
+ if description and description ~= "" then
+ -- First pass: Process all existing SQL code blocks before generating new content
+ local new_blocks = {}
+ for i, block in ipairs(doc.blocks) do
+ if block.t == "CodeBlock" and block.classes and #block.classes > 0 and block.classes[1] == "sql" then
+ local rendered_blocks = render_sql_example(block.text)
+ -- Add all rendered blocks to new_blocks
+ for _, rendered_block in ipairs(rendered_blocks) do
+ table.insert(new_blocks, rendered_block)
+ end
+ else
+ table.insert(new_blocks, block)
+ end
+ end
+ doc.blocks = new_blocks
+
+ -- Second pass: Generate content using _render_meta.py
+ local meta_blocks = render_meta_content(doc)
+
+ if #meta_blocks > 0 then
+ -- Insert after title (first header) if it exists, otherwise at the beginning
+ local insert_pos = 1
+ for i, block in ipairs(doc.blocks) do
+ if block.t == "Header" and block.level == 1 then
+ insert_pos = i + 1
+ break
+ end
+ end
+
+ -- Insert the generated blocks
+ for j, block in ipairs(meta_blocks) do
+ table.insert(doc.blocks, insert_pos + j - 1, block)
+ end
+ end
+ end
+
+ return doc
+end
diff --git a/latest-snapshot/requirements.txt b/latest-snapshot/reference/functions/_matplotlib_defaults.py
similarity index 82%
copy from latest-snapshot/requirements.txt
copy to latest-snapshot/reference/functions/_matplotlib_defaults.py
index 6bd80c39..4baaa176 100644
--- a/latest-snapshot/requirements.txt
+++ b/latest-snapshot/reference/functions/_matplotlib_defaults.py
@@ -15,15 +15,8 @@
# specific language governing permissions and limitations
# under the License.
-griffe
-mike
-mkdocs
-mkdocs-git-revision-date-localized-plugin
-mkdocs-glightbox
-mkdocs-macros-plugin
-mkdocs-material
-mkdocstrings[python]
-nbconvert
-pyproj
-ruff
-lonboard
+import matplotlib.pyplot as plt
+
+plt.rcParams["axes.labelsize"] = 8
+plt.rcParams["xtick.labelsize"] = 8
+plt.rcParams["ytick.labelsize"] = 8
diff --git a/latest-snapshot/reference/functions/_quarto.yml b/latest-snapshot/reference/functions/_quarto.yml
new file mode 100644
index 00000000..331ca253
--- /dev/null
+++ b/latest-snapshot/reference/functions/_quarto.yml
@@ -0,0 +1,46 @@
+# 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.
+
+# This quarto project allows `quarto render` from this directory to be
+# used such that it takes care of executing code blocks to create figures
+# and render standardized frontmatter defining function arguments into
+# usage/argument documentation.
+project:
+ title: "Function Reference"
+format:
+ gfm:
+ # Increase the quality of the figures (the default of 72 is not very
+ # appealing)
+ fig-dpi: 300
+
+# Use jupyter to render python code blocks. We could also use knitr, which
+# is more flexible but requires an R install available.
+engine: jupyter
+
+# By default, don't echo the Python code for Python code blocks. We use these
+# blocks primarily to create figures, not to demo Python code and its output.
+# individual code blocks can add `#| echo: true` to override this default.
+execute:
+ echo: false
+
+# These filters take care of rendering ```sql code blocks, rendering the
+# standardized description/usage/arguments based on document frontmatter,
+# and providing the function-listing shortcode used to list all the functions
+# in index.qmd.
+filters:
+ - _extensions/render-meta-and-examples.lua
+ - _extensions/function-listing
diff --git a/latest-snapshot/reference/functions/_render_examples.py b/latest-snapshot/reference/functions/_render_examples.py
new file mode 100644
index 00000000..1bf1f963
--- /dev/null
+++ b/latest-snapshot/reference/functions/_render_examples.py
@@ -0,0 +1,120 @@
+# 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.
+
+import sedonadb
+
+sd = sedonadb.connect()
+
+
+def render_examples(examples, width=80, ascii=False):
+ """Renders examples to stdout using SedonaDB for Python
+
+ This takes an iterable of example SQL strings and renders the SQL
+ and the result to stdout. All examples are run in the same
+ context.
+
+ Output:
+
+ ````
+
+ ```sql
+ --- examples that don't return a result are accumulated
+ SET some.config = true;
+ --- when a query does return a result, we end the sql code block
+ --- and print the result
+ SELECT one as 1;
+ ```
+
+ ```
+ <output>
+ ```
+
+ ````
+ """
+ try:
+ examples_iter = iter(examples)
+ while True:
+ render_examples_iter_until_result(examples_iter, width=width, ascii=ascii)
+ except StopIteration:
+ pass
+
+
+def render_examples_iter_until_result(examples_iter, width=80, ascii=False):
+ example = next(examples_iter)
+
+ # Open the block where the SQL is printed
+ print("\n```sql")
+ while example is not None:
+ # Execute the example to get a row count. If this is a resultless
+ # statement (no rows, no cols), don't execute it again to print. This
+ # allows SET and CREATE TABLE statements to "set up" examples. We
+ # could also look for a trailing semicolon (e.g., only print results
+ # of statements without a trailing semicolon) if this approach is
+ # problematic.
+
+ # Echo the example
+ print(example.strip())
+
+ # Parse it
+ df = sd.sql(example)
+
+ # Execute and check emptiness
+ if df.execute() == 0 and not df.schema.names:
+ example = next(examples_iter, None)
+ continue
+
+ # Close the ```sql block
+ print("```\n")
+
+ # Print the result block (executes the query again)
+ print("```")
+ df.show(limit=None, width=width, ascii=ascii)
+ print("```")
+ return
+
+ # If we're here, none of the statements had any output, so we need to close
+ # the sql block
+ print("```\n")
+
+
+if __name__ == "__main__":
+ import argparse
+ import sys
+
+ parser = argparse.ArgumentParser(description="Render SedonaDB SQL examples")
+ parser.add_argument(
+ "examples",
+ nargs="+",
+ help=(
+ "SQL strings to be rendered or `-` to read from stdin. "
+ "When reading from stdin, multiple examples may be separated by "
+ "with `----` on its own line."
+ ),
+ )
+ parser.add_argument("--width", type=int, default=80)
+ parser.add_argument("--ascii", default=False, action="store_true")
+
+ args = parser.parse_args(sys.argv[1:])
+ if args.examples == ["-"]:
+ args.examples = sys.stdin.read().split("\n----\n")
+
+ try:
+ render_examples(args.examples, width=args.width, ascii=args.ascii)
+ except Exception as e:
+ raise ValueError(
+ f"Failed to render examples:\n{'\n----\n'.join(args.examples)}"
+ ) from e
diff --git a/latest-snapshot/reference/functions/_render_listing.py b/latest-snapshot/reference/functions/_render_listing.py
new file mode 100644
index 00000000..464e0d01
--- /dev/null
+++ b/latest-snapshot/reference/functions/_render_listing.py
@@ -0,0 +1,83 @@
+# 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.
+
+import io
+from pathlib import Path
+import yaml
+
+from _render_meta import render_meta
+
+
+def render_listing(paths):
+ """Lists meta information for zero or more filenames to function .qmd files
+
+ Output:
+
+ ```
+ ## [ST_Name](st_name.md)
+
+ <description>
+
+ ## Usage
+
+ return_type ST_Name(arg_name: arg_type)
+ ```
+ """
+ for file in paths:
+ raw_meta = read_frontmatter(file)
+ link_href = file.name.replace(".qmd", ".md")
+ print(f"\n## [{raw_meta['title']}]({link_href})\n\n")
+
+ render_meta(raw_meta, level=2, arguments=False)
+
+
+def read_frontmatter(path):
+ frontmatter = io.StringIO()
+ with open(path) as f:
+ for line in f:
+ if line.strip() == "---":
+ break
+ for line in f:
+ if line.strip() == "---":
+ break
+ frontmatter.write(line)
+ frontmatter.seek(0)
+ return yaml.safe_load(frontmatter)
+
+
+def collect_files(file_glob):
+ return list(sorted(Path(__file__).parent.rglob(file_glob)))
+
+
+if __name__ == "__main__":
+ import argparse
+ import sys
+ import yaml
+
+ parser = argparse.ArgumentParser(description="Render SedonaDB SQL function listing")
+ parser.add_argument(
+ "files",
+ nargs="+",
+ help="Files or globs of files whose frontmatter should be included in the listing",
+ )
+ args = parser.parse_args(sys.argv[1:])
+
+ in_files: list[Path] = []
+ for file_or_glob in args.files:
+ in_files.extend(collect_files(file_or_glob))
+
+ render_listing(in_files)
diff --git a/latest-snapshot/reference/functions/_render_meta.py b/latest-snapshot/reference/functions/_render_meta.py
new file mode 100644
index 00000000..e3465a70
--- /dev/null
+++ b/latest-snapshot/reference/functions/_render_meta.py
@@ -0,0 +1,213 @@
+# 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.
+
+import io
+
+
+def render_meta(raw_meta, level=1, usage=True, arguments=True):
+ """Render parsed YAML frontmatter into a standardized template
+
+ Output:
+
+ ```
+ <description>
+
+ ## Usage
+
+ return_type ST_Name(arg_name: arg_type)
+
+ ## Arguments
+
+ - **arg_name** (arg_type): Arg description
+ ```
+
+ """
+ if "description" in raw_meta:
+ render_description(raw_meta["description"])
+
+ if "kernels" in raw_meta:
+ for kernel in raw_meta["kernels"]:
+ kernel["args"] = expand_args(kernel["args"])
+
+ if usage:
+ render_usage(raw_meta["title"], raw_meta["kernels"], level)
+
+ if arguments:
+ render_args(raw_meta["kernels"], level=level)
+
+
+def render_description(description):
+ print(to_str(description).strip())
+
+
+def render_usage(name, kernels, level):
+ print(f"\n{heading(level + 1)} Usage\n")
+ print("\n```sql")
+ for kernel in kernels:
+ args = ", ".join(render_usage_arg(arg) for arg in kernel["args"])
+ print(f"{to_str(kernel['returns'])} {to_str(name)}({args})")
+ print("```")
+
+
+def render_usage_arg(arg):
+ if arg["default"] is not None:
+ return f"{arg['name']}: {arg['type']} = {arg['default']}"
+ else:
+ return f"{arg['name']}: {arg['type']}"
+
+
+def render_args(kernels, level):
+ try:
+ expanded_args = {}
+ for kernel in reversed(kernels):
+ args_dict = {arg["name"]: arg for arg in kernel["args"]}
+ expanded_args.update({k: v for k, v in args_dict.items() if v is not None})
+ except Exception as e:
+ raise ValueError(
+ f"Failed to consolidate argument documentation from kernels:\n{kernels}"
+ ) from e
+
+ print(f"\n{heading(level + 1)} Arguments\n")
+ for arg in expanded_args.values():
+ print(
+ f"- **{to_str(arg['name'])}** ({to_str(arg['type'])}): {to_str(arg['description'])}"
+ )
+
+
+def expand_args(args):
+ """Normalizes frontmatter-specified arguments
+
+ This enables shorthand argument definitions like "geometry" to coexist
+ with more verbosely defined argument definitions.
+ """
+ args = [expand_arg(arg) for arg in args]
+ return deduplicate_common_arg_combinations(args)
+
+
+def deduplicate_common_arg_combinations(expanded_args):
+ """Transform argument names for binary functions with multiple geometry inputs
+
+ Functions like ST_Intersects() that accept two geometries or two geographies
+ will both have auto-generated function names [geom, geom]. This function
+ renames them to [geomA, geomB].
+ """
+ all_names = [arg["name"] for arg in expanded_args]
+ if all_names[:2] == ["geom", "geom"]:
+ all_names[:2] = ["geomA", "geomB"]
+ elif all_names[:2] == ["geog", "geog"]:
+ all_names[:2] = ["geogA", "geogB"]
+
+ return [
+ {
+ "name": new_name,
+ "type": arg["type"],
+ "description": arg["description"],
+ "default": arg["default"],
+ }
+ for arg, new_name in zip(expanded_args, all_names)
+ ]
+
+
+def expand_arg(arg):
+ """Ensure each arg definition is a dict with keys type, name, description,
+ and default
+ """
+ if isinstance(arg, dict):
+ arg = {k: to_str(v) for k, v in arg.items()}
+ else:
+ arg = to_str(arg)
+ arg = {
+ "type": arg,
+ "name": DEFAULT_ARG_NAMES[arg],
+ "description": DEFAULT_ARG_DESCRIPTIONS.get(arg, None),
+ }
+
+ if "default" not in arg:
+ arg["default"] = None
+ if "description" not in arg:
+ arg["description"] = None
+
+ return arg
+
+
+# Define some default argument names/descriptions so that we can abbreviate
+# the ubiquitous "geometry" input type argument without repeating the string
+# "geom: Input geometry" for every single function.
+DEFAULT_ARG_NAMES = {
+ "geometry": "geom",
+ "geography": "geog",
+ "raster": "rast",
+}
+
+DEFAULT_ARG_DESCRIPTIONS = {
+ "geometry": "Input geometry",
+ "geography": "Input geography",
+ "raster": "Input raster",
+}
+
+
+def heading(level):
+ return "#" * level + " "
+
+
+def to_str(v):
+ """Convert a value to a string
+
+ Because we call this from within a Quarto filter and use pandoc's built-in
+ JSON output, we might get a pandoc JSONified AST here. Parsing the AST here
+ is slightly easier than getting the Quarto filter to recreate the initial
+ YAML frontmatter.
+ """
+ if isinstance(v, str):
+ return v
+
+ if isinstance(v, dict):
+ if v["t"] == "Str":
+ return v["c"]
+ if v["t"] == "Code":
+ return f"`{v['c'][1]}`"
+ elif v["t"] == "Space":
+ return " "
+ elif v["t"] == "Para":
+ return "".join(to_str(item) for item in v["c"])
+ else:
+ raise ValueError(f"Unhandled type in Pandoc ast convert: {v}")
+ else:
+ return "".join(to_str(item) for item in v)
+
+
+if __name__ == "__main__":
+ import argparse
+ import sys
+ import yaml
+
+ parser = argparse.ArgumentParser(description="Render SedonaDB SQL function header")
+ parser.add_argument(
+ "meta",
+ help=(
+ "Function yaml metadata (e.g., frontmatter for a function doc page). "
+ "Use `-` to read stdin."
+ ),
+ )
+
+ args = parser.parse_args(sys.argv[1:])
+ if args.meta == "-":
+ args.meta = sys.stdin.read()
+
+ with io.StringIO(args.meta) as f:
+ raw_meta = yaml.safe_load(f)
+ render_meta(raw_meta)
diff --git a/latest-snapshot/requirements.txt b/latest-snapshot/reference/functions/index.qmd
similarity index 82%
copy from latest-snapshot/requirements.txt
copy to latest-snapshot/reference/functions/index.qmd
index 6bd80c39..7c2ea8c6 100644
--- a/latest-snapshot/requirements.txt
+++ b/latest-snapshot/reference/functions/index.qmd
@@ -1,3 +1,4 @@
+---
# 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
@@ -15,15 +16,7 @@
# specific language governing permissions and limitations
# under the License.
-griffe
-mike
-mkdocs
-mkdocs-git-revision-date-localized-plugin
-mkdocs-glightbox
-mkdocs-macros-plugin
-mkdocs-material
-mkdocstrings[python]
-nbconvert
-pyproj
-ruff
-lonboard
+title: "SQL Function Reference"
+---
+
+{{< function-listing st_*.qmd >}}
diff --git a/latest-snapshot/reference/functions/st_analyze_agg.qmd b/latest-snapshot/reference/functions/st_analyze_agg.qmd
new file mode 100644
index 00000000..e9b1de6a
--- /dev/null
+++ b/latest-snapshot/reference/functions/st_analyze_agg.qmd
@@ -0,0 +1,49 @@
+---
+# 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.
+
+title: ST_Analyze_Agg
+description: Compute the statistics of geometries for the input geometry.
+kernels:
+ - returns: struct
+ args: [geometry]
+---
+
+## Description
+
+`ST_Analyze_Agg()` provides a high-level summary of its input geometries. The fields of
+its struct return type are:
+
+- `count`: Number of input geometries
+- `minx`, `miny`, `maxx`, `maxy`: Minimum bounding rectangle (envelope)
+- `mean_size_in_bytes`
+- `mean_points_per_geometry`
+- `puntal_count`: Number of point or multipoint geometries
+- `lineal_count`: Number of line or multilinestring geometries
+- `polygonal_count`: Number of polygon or multipolygon geometries
+- `geometrycollection_count`: Number of geometrycollection geometries
+- `mean_envelope_width`
+- `mean_envelope_height`
+- `mean_envelope_area`
+
+## Examples
+
+```sql
+SELECT ST_Analyze_Agg(
+ ST_GeomFromText('MULTIPOINT(1.1 101.1,2.1 102.1,3.1 103.1,4.1 104.1,5.1 105.1,6.1 106.1,7.1 107.1,8.1 108.1,9.1 109.1,10.1 110.1)')
+ ) AS analyze
+```
diff --git a/latest-snapshot/reference/functions/st_buffer.qmd b/latest-snapshot/reference/functions/st_buffer.qmd
new file mode 100644
index 00000000..64f807c8
--- /dev/null
+++ b/latest-snapshot/reference/functions/st_buffer.qmd
@@ -0,0 +1,81 @@
+---
+# 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.
+
+title: ST_Buffer
+description: >
+ Computes a geometry that represents all points whose distance from the input
+ geometry is less than or equal to a specified distance.
+kernels:
+ - returns: geometry
+ args:
+ - geometry
+ - name: distance
+ type: float64
+ description: Radius of the buffer
+ - returns: geometry
+ args:
+ - geometry
+ - name: distance
+ type: float64
+ - name: params
+ type: utf8
+ description: >
+ Space-separated `key=value` parameters. Supported parameters include `quad_segs`,
+ `endcap`, `join`, `mitre_limit`, and `side`. These parameters are identical to
+ the PostGIS buffer parameter strings.
+---
+
+## Examples
+
+```sql
+SELECT ST_Buffer(
+ ST_GeomFromText('POLYGON ((10 10, 11 10, 10 11, 10 10))'),
+ 1.0
+) AS geom;
+```
+
+```{python}
+import _matplotlib_defaults
+import sedonadb
+
+sd = sedonadb.connect()
+
+sd.sql("""
+SELECT ST_GeomFromText('POLYGON ((10 10, 11 10, 10 11, 10 10))') as geom
+""").to_view("input")
+
+df = sd.sql("SELECT *, ST_Buffer(geom, 1.0) AS result FROM input").to_pandas()
+
+ax = df.geom.plot(alpha=0.5)
+df.result.plot(ax=ax, facecolor='none', edgecolor='red')
+```
+
+```sql
+SELECT ST_Buffer(
+ ST_GeomFromText('POLYGON ((10 10, 11 10, 10 11, 10 10))'),
+ 1.0,
+ 'quad_segs=2'
+) AS geom;
+```
+
+```{python}
+df = sd.sql("SELECT *, ST_Buffer(geom, 1.0, 'quad_segs=2') AS result FROM input").to_pandas()
+
+ax = df.geom.plot(alpha=0.5)
+df.result.plot(ax=ax, facecolor='none', edgecolor='red')
+```
diff --git a/latest-snapshot/reference/functions/st_intersection.qmd b/latest-snapshot/reference/functions/st_intersection.qmd
new file mode 100644
index 00000000..2bdc47be
--- /dev/null
+++ b/latest-snapshot/reference/functions/st_intersection.qmd
@@ -0,0 +1,54 @@
+---
+# 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.
+
+title: ST_Intersection
+description: Compute the intersection of two geometries or geographies.
+kernels:
+ - returns: geometry
+ args: [geometry, geometry]
+ - returns: geography
+ args: [geography, geography]
+---
+
+## Examples
+
+```sql
+SELECT ST_Intersection(
+ ST_GeomFromText('POLYGON ((1 1, 11 1, 11 11, 1 11, 1 1))'),
+ ST_GeomFromText('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))')
+) AS val;
+```
+
+```{python}
+import _matplotlib_defaults
+import sedonadb
+
+sd = sedonadb.connect()
+
+sd.sql("""
+SELECT
+ ST_GeomFromText('POLYGON ((1 1, 11 1, 11 11, 1 11, 1 1))') as geom_a,
+ ST_GeomFromText('POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))') as geom_b
+""").to_view("input")
+
+df = sd.sql("SELECT *, ST_Intersection(geom_a, geom_b) as result FROM input").to_pandas()
+
+ax = df.geom_a.plot(alpha=0.5)
+df.geom_b.plot(ax=ax, alpha=0.5)
+df.result.plot(ax=ax, facecolor='none', edgecolor='red')
+```
diff --git a/latest-snapshot/requirements.txt b/latest-snapshot/requirements.txt
index 6bd80c39..53f6716c 100644
--- a/latest-snapshot/requirements.txt
+++ b/latest-snapshot/requirements.txt
@@ -16,6 +16,7 @@
# under the License.
griffe
+ipykernel
mike
mkdocs
mkdocs-git-revision-date-localized-plugin
diff --git a/latest-snapshot/search/search_index.json b/latest-snapshot/search/search_index.json
index 104f8e32..ebe40416 100644
--- a/latest-snapshot/search/search_index.json
+++ b/latest-snapshot/search/search_index.json
@@ -1 +1 @@
-{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Introducing SedonaDB","text":"<p>SedonaDB is an open-source single-node analytical database engine with geospatial as a first-class citizen. It aims to deliver the fastest spatial analytics query speed and the most comprehensive function coverage available.</p> <p>SedonaDB is perfect for process [...]
\ No newline at end of file
+{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"],"fields":{"title":{"boost":1000.0},"text":{"boost":1.0},"tags":{"boost":1000000.0}}},"docs":[{"location":"","title":"Introducing SedonaDB","text":"<p>SedonaDB is an open-source single-node analytical database engine with geospatial as a first-class citizen. It aims to deliver the fastest spatial analytics query speed and the most comprehensive function coverage available.</p> <p>SedonaDB is perfect for process [...]
\ No newline at end of file