blob: da7279bc5d9ce09abdd5f295d4823a0aff72fcbe [file] [log] [blame]
<!DOCTYPE html>
<html lang="en" data-content_root="" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<title>Gandiva External Functions Development Guide &#8212; Apache Arrow v17.0.0.dev52</title>
<script data-cfasync="false">
document.documentElement.dataset.mode = localStorage.getItem("mode") || "";
document.documentElement.dataset.theme = localStorage.getItem("theme") || "light";
</script>
<!-- Loaded before other Sphinx assets -->
<link href="../../_static/styles/theme.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link href="../../_static/styles/bootstrap.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link href="../../_static/styles/pydata-sphinx-theme.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link href="../../_static/vendor/fontawesome/6.5.1/css/all.min.css?digest=8d27b9dea8ad943066ae" rel="stylesheet" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../../_static/vendor/fontawesome/6.5.1/webfonts/fa-solid-900.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../../_static/vendor/fontawesome/6.5.1/webfonts/fa-brands-400.woff2" />
<link rel="preload" as="font" type="font/woff2" crossorigin href="../../_static/vendor/fontawesome/6.5.1/webfonts/fa-regular-400.woff2" />
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../../_static/design-style.1e8bd061cd6da7fc9cf755528e8ffc24.min.css" />
<link rel="stylesheet" type="text/css" href="../../_static/theme_overrides.css" />
<!-- Pre-loaded scripts that we'll load fully later -->
<link rel="preload" as="script" href="../../_static/scripts/bootstrap.js?digest=8d27b9dea8ad943066ae" />
<link rel="preload" as="script" href="../../_static/scripts/pydata-sphinx-theme.js?digest=8d27b9dea8ad943066ae" />
<script src="../../_static/vendor/fontawesome/6.5.1/js/all.min.js?digest=8d27b9dea8ad943066ae"></script>
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/sphinx_highlight.js"></script>
<script src="../../_static/clipboard.min.js"></script>
<script src="../../_static/copybutton.js"></script>
<script src="../../_static/design-tabs.js"></script>
<script>DOCUMENTATION_OPTIONS.pagename = 'cpp/gandiva/external_func';</script>
<script>
DOCUMENTATION_OPTIONS.theme_version = '0.15.2';
DOCUMENTATION_OPTIONS.theme_switcher_json_url = '/docs/_static/versions.json';
DOCUMENTATION_OPTIONS.theme_switcher_version_match = 'dev/';
DOCUMENTATION_OPTIONS.show_version_warning_banner = true;
</script>
<link rel="canonical" href="https://arrow.apache.org/docs/cpp/gandiva/external_func.html" />
<link rel="icon" href="../../_static/favicon.ico"/>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="next" title="Acero: A C++ streaming execution engine" href="../streaming_execution.html" />
<link rel="prev" title="Gandiva Expression, Projector, and Filter" href="expr_projector_filter.html" />
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<meta name="docsearch:language" content="en"/>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
/* We explicitly disable cookie tracking to avoid privacy issues */
_paq.push(['disableCookies']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '20']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</head>
<body data-bs-spy="scroll" data-bs-target=".bd-toc-nav" data-offset="180" data-bs-root-margin="0px 0px -60%" data-default-mode="">
<a id="pst-skip-link" class="skip-link" href="#main-content">Skip to main content</a>
<div id="pst-scroll-pixel-helper"></div>
<button type="button" class="btn rounded-pill" id="pst-back-to-top">
<i class="fa-solid fa-arrow-up"></i>
Back to top
</button>
<input type="checkbox"
class="sidebar-toggle"
name="__primary"
id="__primary"/>
<label class="overlay overlay-primary" for="__primary"></label>
<input type="checkbox"
class="sidebar-toggle"
name="__secondary"
id="__secondary"/>
<label class="overlay overlay-secondary" for="__secondary"></label>
<div class="search-button__wrapper">
<div class="search-button__overlay"></div>
<div class="search-button__search-container">
<form class="bd-search d-flex align-items-center"
action="../../search.html"
method="get">
<i class="fa-solid fa-magnifying-glass"></i>
<input type="search"
class="form-control"
name="q"
id="search-input"
placeholder="Search the docs ..."
aria-label="Search the docs ..."
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</form></div>
</div>
<header class="bd-header navbar navbar-expand-lg bd-navbar">
<div class="bd-header__inner bd-page-width">
<label class="sidebar-toggle primary-toggle" for="__primary">
<span class="fa-solid fa-bars"></span>
</label>
<div class="col-lg-3 navbar-header-items__start">
<div class="navbar-item">
<a class="navbar-brand logo" href="../../index.html">
<img src="../../_static/arrow.png" class="logo__image only-light" alt="Apache Arrow v17.0.0.dev52 - Home"/>
<script>document.write(`<img src="../../_static/arrow-dark.png" class="logo__image only-dark" alt="Apache Arrow v17.0.0.dev52 - Home"/>`);</script>
</a></div>
</div>
<div class="col-lg-9 navbar-header-items">
<div class="me-auto navbar-header-items__center">
<div class="navbar-item">
<nav class="navbar-nav">
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item">
<a class="nav-link nav-internal" href="../../format/index.html">
Specifications
</a>
</li>
<li class="nav-item">
<a class="nav-link nav-internal" href="../../developers/index.html">
Development
</a>
</li>
<li class="nav-item dropdown">
<button class="btn dropdown-toggle nav-item" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-controls="pst-nav-more-links">
Implementations
</button>
<ul id="pst-nav-more-links" class="dropdown-menu">
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../c_glib/index.html">
C/GLib
</a>
</li>
<li class="nav-item current active">
<a class="nav-link dropdown-item nav-internal" href="../index.html">
C++
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://github.com/apache/arrow/blob/main/csharp/README.md">
C#
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://pkg.go.dev/github.com/apache/arrow/go/v17">
Go
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../java/index.html">
Java
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../js/index.html">
JavaScript
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/julia/">
Julia
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://github.com/apache/arrow/blob/main/matlab/README.md">
MATLAB
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/nanoarrow/">
nanoarrow
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../python/index.html">
Python
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../r/index.html">
R
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://github.com/apache/arrow/blob/main/ruby/README.md">
Ruby
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://docs.rs/crate/arrow/">
Rust
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../status.html">
Implementation Status
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/cpp/">
C++ cookbook
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/java/">
Java cookbook
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/py/">
Python cookbook
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/r/">
R cookbook
</a>
</li>
</ul>
</li>
</ul>
</nav></div>
</div>
<div class="navbar-header-items__end">
<div class="navbar-item navbar-persistent--container">
<script>
document.write(`
<button class="btn navbar-btn search-button-field search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
`);
</script>
</div>
<div class="navbar-item">
<script>
document.write(`
<div class="version-switcher__container dropdown">
<button id="pst-version-switcher-button-2"
type="button"
class="version-switcher__button btn btn-sm navbar-btn dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="listbox"
aria-controls="pst-version-switcher-list-2"
aria-label="Version switcher list"
>
Choose version <!-- this text may get changed later by javascript -->
<span class="caret"></span>
</button>
<div id="pst-version-switcher-list-2"
class="version-switcher__menu dropdown-menu list-group-flush py-0"
role="listbox" aria-labelledby="pst-version-switcher-button-2">
<!-- dropdown will be populated by javascript on page load -->
</div>
</div>
`);
</script></div>
<div class="navbar-item">
<script>
document.write(`
<button class="btn btn-sm navbar-btn theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="theme-switch nav-link" data-mode="light"><i class="fa-solid fa-sun fa-lg"></i></span>
<span class="theme-switch nav-link" data-mode="dark"><i class="fa-solid fa-moon fa-lg"></i></span>
<span class="theme-switch nav-link" data-mode="auto"><i class="fa-solid fa-circle-half-stroke fa-lg"></i></span>
</button>
`);
</script></div>
<div class="navbar-item"><ul class="navbar-icon-links navbar-nav"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://github.com/apache/arrow" title="GitHub" class="nav-link" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><span><i class="fa-brands fa-square-github fa-lg" aria-hidden="true"></i></span>
<span class="sr-only">GitHub</span></a>
</li>
<li class="nav-item">
<a href="https://twitter.com/ApacheArrow" title="X" class="nav-link" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><span><i class="fa-brands fa-square-x-twitter fa-lg" aria-hidden="true"></i></span>
<span class="sr-only">X</span></a>
</li>
</ul></div>
</div>
</div>
<div class="navbar-persistent--mobile">
<script>
document.write(`
<button class="btn navbar-btn search-button-field search-button__button" title="Search" aria-label="Search" data-bs-placement="bottom" data-bs-toggle="tooltip">
<i class="fa-solid fa-magnifying-glass"></i>
<span class="search-button__default-text">Search</span>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd class="kbd-shortcut__modifier">K</kbd></span>
</button>
`);
</script>
</div>
<label class="sidebar-toggle secondary-toggle" for="__secondary" tabindex="0">
<span class="fa-solid fa-outdent"></span>
</label>
</div>
</header>
<div class="bd-container">
<div class="bd-container__inner bd-page-width">
<div class="bd-sidebar-primary bd-sidebar">
<div class="sidebar-header-items sidebar-primary__section">
<div class="sidebar-header-items__center">
<div class="navbar-item">
<nav class="navbar-nav">
<ul class="bd-navbar-elements navbar-nav">
<li class="nav-item">
<a class="nav-link nav-internal" href="../../format/index.html">
Specifications
</a>
</li>
<li class="nav-item">
<a class="nav-link nav-internal" href="../../developers/index.html">
Development
</a>
</li>
<li class="nav-item dropdown">
<button class="btn dropdown-toggle nav-item" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-controls="pst-nav-more-links-2">
Implementations
</button>
<ul id="pst-nav-more-links-2" class="dropdown-menu">
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../c_glib/index.html">
C/GLib
</a>
</li>
<li class="nav-item current active">
<a class="nav-link dropdown-item nav-internal" href="../index.html">
C++
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://github.com/apache/arrow/blob/main/csharp/README.md">
C#
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://pkg.go.dev/github.com/apache/arrow/go/v17">
Go
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../java/index.html">
Java
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../js/index.html">
JavaScript
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/julia/">
Julia
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://github.com/apache/arrow/blob/main/matlab/README.md">
MATLAB
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/nanoarrow/">
nanoarrow
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../python/index.html">
Python
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../r/index.html">
R
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://github.com/apache/arrow/blob/main/ruby/README.md">
Ruby
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://docs.rs/crate/arrow/">
Rust
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-internal" href="../../status.html">
Implementation Status
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/cpp/">
C++ cookbook
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/java/">
Java cookbook
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/py/">
Python cookbook
</a>
</li>
<li class="nav-item">
<a class="nav-link dropdown-item nav-external" href="https://arrow.apache.org/cookbook/r/">
R cookbook
</a>
</li>
</ul>
</li>
</ul>
</nav></div>
</div>
<div class="sidebar-header-items__end">
<div class="navbar-item">
<script>
document.write(`
<div class="version-switcher__container dropdown">
<button id="pst-version-switcher-button-3"
type="button"
class="version-switcher__button btn btn-sm navbar-btn dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="listbox"
aria-controls="pst-version-switcher-list-3"
aria-label="Version switcher list"
>
Choose version <!-- this text may get changed later by javascript -->
<span class="caret"></span>
</button>
<div id="pst-version-switcher-list-3"
class="version-switcher__menu dropdown-menu list-group-flush py-0"
role="listbox" aria-labelledby="pst-version-switcher-button-3">
<!-- dropdown will be populated by javascript on page load -->
</div>
</div>
`);
</script></div>
<div class="navbar-item">
<script>
document.write(`
<button class="btn btn-sm navbar-btn theme-switch-button" title="light/dark" aria-label="light/dark" data-bs-placement="bottom" data-bs-toggle="tooltip">
<span class="theme-switch nav-link" data-mode="light"><i class="fa-solid fa-sun fa-lg"></i></span>
<span class="theme-switch nav-link" data-mode="dark"><i class="fa-solid fa-moon fa-lg"></i></span>
<span class="theme-switch nav-link" data-mode="auto"><i class="fa-solid fa-circle-half-stroke fa-lg"></i></span>
</button>
`);
</script></div>
<div class="navbar-item"><ul class="navbar-icon-links navbar-nav"
aria-label="Icon Links">
<li class="nav-item">
<a href="https://github.com/apache/arrow" title="GitHub" class="nav-link" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><span><i class="fa-brands fa-square-github fa-lg" aria-hidden="true"></i></span>
<span class="sr-only">GitHub</span></a>
</li>
<li class="nav-item">
<a href="https://twitter.com/ApacheArrow" title="X" class="nav-link" rel="noopener" target="_blank" data-bs-toggle="tooltip" data-bs-placement="bottom"><span><i class="fa-brands fa-square-x-twitter fa-lg" aria-hidden="true"></i></span>
<span class="sr-only">X</span></a>
</li>
</ul></div>
</div>
</div>
<div class="sidebar-primary-items__start sidebar-primary__section">
<div class="sidebar-primary-item">
<nav class="bd-docs-nav bd-links"
aria-label="Section Navigation">
<p class="bd-links__title" role="heading" aria-level="1">Section Navigation</p>
<div class="bd-toc-item navbar-nav"><ul class="current nav bd-sidenav">
<li class="toctree-l1 has-children"><a class="reference internal" href="../getting_started.html">Getting Started</a><input class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" type="checkbox"/><label class="toctree-toggle" for="toctree-checkbox-1"><i class="fa-solid fa-chevron-down"></i></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../build_system.html">Using Arrow C++ in your own project</a></li>
<li class="toctree-l2"><a class="reference internal" href="../conventions.html">Conventions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorials/basic_arrow.html">Basic Arrow Data Structures</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorials/io_tutorial.html">Arrow File I/O</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorials/compute_tutorial.html">Arrow Compute</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorials/datasets_tutorial.html">Arrow Datasets</a></li>
</ul>
</li>
<li class="toctree-l1 current active has-children"><a class="reference internal" href="../user_guide.html">User Guide</a><input checked="" class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" type="checkbox"/><label class="toctree-toggle" for="toctree-checkbox-2"><i class="fa-solid fa-chevron-down"></i></label><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../overview.html">High-Level Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="../memory.html">Memory Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../arrays.html">Arrays</a></li>
<li class="toctree-l2"><a class="reference internal" href="../datatypes.html">Data Types</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tables.html">Tabular Data</a></li>
<li class="toctree-l2"><a class="reference internal" href="../compute.html">Compute Functions</a></li>
<li class="toctree-l2 current active has-children"><a class="reference internal" href="../gandiva.html">The Gandiva Expression Compiler</a><input checked="" class="toctree-checkbox" id="toctree-checkbox-3" name="toctree-checkbox-3" type="checkbox"/><label class="toctree-toggle" for="toctree-checkbox-3"><i class="fa-solid fa-chevron-down"></i></label><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="expr_projector_filter.html">Gandiva Expression, Projector, and Filter</a></li>
<li class="toctree-l3 current active"><a class="current reference internal" href="#">Gandiva External Functions Development Guide</a></li>
</ul>
</li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../streaming_execution.html">Acero: A C++ streaming execution engine</a><input class="toctree-checkbox" id="toctree-checkbox-4" name="toctree-checkbox-4" type="checkbox"/><label class="toctree-toggle" for="toctree-checkbox-4"><i class="fa-solid fa-chevron-down"></i></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../acero/overview.html">Acero Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../acero/user_guide.html">Acero User’s Guide</a></li>
<li class="toctree-l3"><a class="reference internal" href="../acero/substrait.html">Using Acero with Substrait</a></li>
<li class="toctree-l3"><a class="reference internal" href="../acero/developer_guide.html">Developer’s Guide</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../io.html">Input / output and filesystems</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ipc.html">Reading and writing the Arrow IPC format</a></li>
<li class="toctree-l2"><a class="reference internal" href="../orc.html">Reading and Writing ORC files</a></li>
<li class="toctree-l2"><a class="reference internal" href="../parquet.html">Reading and writing Parquet files</a></li>
<li class="toctree-l2"><a class="reference internal" href="../csv.html">Reading and Writing CSV files</a></li>
<li class="toctree-l2"><a class="reference internal" href="../json.html">Reading JSON files</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dataset.html">Tabular Datasets</a></li>
<li class="toctree-l2"><a class="reference internal" href="../flight.html">Arrow Flight RPC</a></li>
<li class="toctree-l2"><a class="reference internal" href="../gdb.html">Debugging code using Arrow</a></li>
<li class="toctree-l2"><a class="reference internal" href="../threading.html">Thread Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../opentelemetry.html">OpenTelemetry</a></li>
<li class="toctree-l2"><a class="reference internal" href="../env_vars.html">Environment Variables</a></li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../examples/index.html">Examples</a><input class="toctree-checkbox" id="toctree-checkbox-5" name="toctree-checkbox-5" type="checkbox"/><label class="toctree-toggle" for="toctree-checkbox-5"><i class="fa-solid fa-chevron-down"></i></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../examples/cmake_minimal_build.html">Minimal build using CMake</a></li>
<li class="toctree-l2"><a class="reference internal" href="../examples/compute_and_write_example.html">Compute and Write CSV Example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../examples/dataset_documentation_example.html">Arrow Datasets example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../examples/dataset_skyhook_scan_example.html">Arrow Skyhook example</a></li>
<li class="toctree-l2"><a class="reference internal" href="../examples/row_columnar_conversion.html">Row to columnar conversion</a></li>
<li class="toctree-l2"><a class="reference internal" href="../examples/tuple_range_conversion.html">std::tuple-like ranges to Arrow</a></li>
<li class="toctree-l2"><a class="reference internal" href="../examples/converting_recordbatch_to_tensor.html">Converting RecordBatch to Tensor</a></li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../api.html">API Reference</a><input class="toctree-checkbox" id="toctree-checkbox-6" name="toctree-checkbox-6" type="checkbox"/><label class="toctree-toggle" for="toctree-checkbox-6"><i class="fa-solid fa-chevron-down"></i></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../api/support.html">Programming Support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/memory.html">Memory (management)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/thread.html">Thread (management)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/datatype.html">Data Types</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/array.html">Arrays</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/scalar.html">Scalars</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/builder.html">Array Builders</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/table.html">Two-dimensional Datasets</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/c_abi.html">C Interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/compute.html">Compute Functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/acero.html">Streaming Execution (Acero)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/gandiva.html">Gandiva Expression Compiler</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/tensor.html">Tensors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/utilities.html">Utilities</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/async.html">Asynchronous programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/io.html">Input / output</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/ipc.html">Arrow IPC</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/formats.html">File Formats</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/cuda.html">CUDA support</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/flight.html">Arrow Flight RPC</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/flightsql.html">Arrow Flight SQL</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/filesystem.html">Filesystems</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/dataset.html">Dataset</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference external" href="https://arrow.apache.org/cookbook/cpp/">C++ cookbook</a></li>
</ul>
</div>
</nav></div>
</div>
<div class="sidebar-primary-items__end sidebar-primary__section">
</div>
<div id="rtd-footer-container"></div>
</div>
<main id="main-content" class="bd-main">
<div class="bd-content">
<div class="bd-article-container">
<div class="bd-header-article">
<div class="header-article-items header-article__inner">
<div class="header-article-items__start">
<div class="header-article-item">
<nav aria-label="Breadcrumb">
<ul class="bd-breadcrumbs">
<li class="breadcrumb-item breadcrumb-home">
<a href="../../index.html" class="nav-link" aria-label="Home">
<i class="fa-solid fa-home"></i>
</a>
</li>
<li class="breadcrumb-item"><a href="../index.html" class="nav-link">C++ Implementation</a></li>
<li class="breadcrumb-item"><i class="fa-solid fa-ellipsis"></i></li>
<li class="breadcrumb-item"><a href="../gandiva.html" class="nav-link">The Gandiva Expression Compiler</a></li>
<li class="breadcrumb-item active" aria-current="page">Gandiva...</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<div id="searchbox"></div>
<article class="bd-article">
<section id="gandiva-external-functions-development-guide">
<h1>Gandiva External Functions Development Guide<a class="headerlink" href="#gandiva-external-functions-development-guide" title="Permalink to this heading">#</a></h1>
<section id="introduction">
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this heading">#</a></h2>
<p>Gandiva, as an analytical expression compiler framework, extends its functionality through external functions. This guide is focused on helping developers understand, create, and integrate external functions into Gandiva. External functions are user-defined, third-party functions that can be used in Gandiva expressions.</p>
</section>
<section id="overview-of-external-function-types-in-gandiva">
<h2>Overview of External Function Types in Gandiva<a class="headerlink" href="#overview-of-external-function-types-in-gandiva" title="Permalink to this heading">#</a></h2>
<p>Gandiva supports two primary types of external functions:</p>
<ul class="simple">
<li><p>C Functions: Functions conforming to the C calling convention. Developers can implement functions in various languages (like C++, Rust, C, or Zig) and expose them as C functions to Gandiva.</p></li>
<li><p>IR Functions: Functions implemented in LLVM Intermediate Representation (LLVM IR). These can be written in multiple languages and then compiled into LLVM IR to be registered in Gandiva.</p></li>
</ul>
<section id="choosing-the-right-type-of-external-function-for-your-needs">
<h3>Choosing the Right Type of External Function for Your Needs<a class="headerlink" href="#choosing-the-right-type-of-external-function-for-your-needs" title="Permalink to this heading">#</a></h3>
<p>When integrating external functions into Gandiva, it’s crucial to select the type that best fits your specific requirements. Here are the key distinctions between C Functions and IR Functions to guide your decision:</p>
<ul class="simple">
<li><dl class="simple">
<dt>C Functions</dt><dd><ul>
<li><p><strong>Language Flexibility:</strong> C functions offer the flexibility to implement your logic in a preferred programming language and subsequently expose them as C functions.</p></li>
<li><p><strong>Broad Applicability:</strong> They are generally a go-to choice for a wide range of use cases due to their compatibility and ease of integration.</p></li>
</ul>
</dd>
</dl>
</li>
<li><dl class="simple">
<dt>IR Functions</dt><dd><ul>
<li><p><strong>Recommended Use Cases:</strong> IR functions excel in handling straightforward tasks that do not require elaborate logic or dependence on sophisticated third-party libraries. Unlike C functions, IR functions have the advantage of being inlinable, which is particularly beneficial for simple operations where the invocation overhead constitutes a significant expense. Additionally, they are an ideal choice for projects that are already integrated with the LLVM toolchain.</p></li>
<li><p><strong>IR Compilation Requirement:</strong> For IR functions, the entire implementation, including any third-party libraries used, must be compiled into LLVM IR. This might affect performance, especially if the dependent libraries are complex.</p></li>
<li><p><strong>Limitations in Capabilities:</strong> Certain advanced features, such as using thread-local variables, are not supported in IR functions. This is due to the limitations of the current JIT (Just-In-Time) engine utilized internally by Gandiva.</p></li>
</ul>
</dd>
</dl>
</li>
</ul>
<img alt="External C functions and IR functions integrating with Gandiva" src="../../_images/external_func.png" />
</section>
</section>
<section id="external-function-registration">
<h2>External function registration<a class="headerlink" href="#external-function-registration" title="Permalink to this heading">#</a></h2>
<p>To make a function available to Gandiva, you need to register it as an external function, providing both a function’s metadata and its implementation to Gandiva.</p>
<section id="metadata-registration-using-the-nativefunction-class">
<h3>Metadata Registration Using the <code class="docutils literal notranslate"><span class="pre">NativeFunction</span></code> Class<a class="headerlink" href="#metadata-registration-using-the-nativefunction-class" title="Permalink to this heading">#</a></h3>
<p>To register a function in Gandiva, use the <code class="docutils literal notranslate"><span class="pre">gandiva::NativeFunction</span></code> class. This class captures both the signature and metadata of the external function.</p>
<p>Constructor Details for <code class="docutils literal notranslate"><span class="pre">gandiva::NativeFunction</span></code>:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="n">NativeFunction</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span><span class="w"> </span><span class="n">base_name</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">aliases</span><span class="p">,</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">DataTypeVector</span><span class="o">&amp;</span><span class="w"> </span><span class="n">param_types</span><span class="p">,</span><span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">DataTypePtr</span><span class="o">&amp;</span><span class="w"> </span><span class="n">ret_type</span><span class="p">,</span>
<span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">ResultNullableType</span><span class="o">&amp;</span><span class="w"> </span><span class="n">result_nullable_type</span><span class="p">,</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="w"> </span><span class="n">pc_name</span><span class="p">,</span>
<span class="w"> </span><span class="kt">int32_t</span><span class="w"> </span><span class="n">flags</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">NativeFunction</span></code> class is used to define the metadata for an external function. Here is a breakdown of its constructor parameters:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">base_name</span></code>: The name of the function as it will be used in expressions.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">aliases</span></code>: A list of alternative names for the function.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">param_types</span></code>: A vector of <code class="docutils literal notranslate"><span class="pre">arrow::DataType</span></code> objects representing the types of the parameters that the function accepts.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ret_type</span></code>: A <code class="docutils literal notranslate"><span class="pre">std::shared_ptr&lt;arrow::DataType&gt;</span></code> representing the return type of the function.</p></li>
<li><dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">result_nullable_type</span></code>: This parameter indicates whether the result can be null, based on the nullability of the input arguments. It can take one of the following values:</dt><dd><ul>
<li><p><code class="docutils literal notranslate"><span class="pre">ResultNullableType::kResultNullIfNull</span></code>: result validity is an intersection of the validity of the children.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ResultNullableType::kResultNullNever</span></code>: result is always valid.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">ResultNullableType::kResultNullInternal</span></code>: result validity depends on some internal logic.</p></li>
</ul>
</dd>
</dl>
</li>
<li><p><code class="docutils literal notranslate"><span class="pre">pc_name</span></code>: The name of the corresponding precompiled function.
* Typically, this name follows the convention <code class="docutils literal notranslate"><span class="pre">{base_name}</span></code> + <code class="docutils literal notranslate"><span class="pre">_{param1_type}</span></code> + <code class="docutils literal notranslate"><span class="pre">{param2_type}</span></code> + … + <code class="docutils literal notranslate"><span class="pre">{paramN_type}</span></code>. For example, if the base name is <code class="docutils literal notranslate"><span class="pre">add</span></code> and the function takes two <code class="docutils literal notranslate"><span class="pre">int32</span></code> parameters and returns an <code class="docutils literal notranslate"><span class="pre">int32</span></code>, the precompiled function name would be <code class="docutils literal notranslate"><span class="pre">add_int32_int32</span></code>, but this convention is not mandatory as long as you can guarantee its uniqueness.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">flags</span></code>: Optional flags for additional function attributes (default is 0). Please check out <code class="docutils literal notranslate"><span class="pre">NativeFunction::kNeedsContext</span></code>, <code class="docutils literal notranslate"><span class="pre">NativeFunction::kNeedsFunctionHolder</span></code>, and <code class="docutils literal notranslate"><span class="pre">NativeFunction::kCanReturnErrors</span></code> for more details.</p></li>
</ul>
<p>After the function is registered, its implementation needs to be provided via either a C function pointer or a LLVM IR function.</p>
</section>
<section id="external-c-functions">
<h3>External C functions<a class="headerlink" href="#external-c-functions" title="Permalink to this heading">#</a></h3>
<p>External C functions can be authored in different languages and exposed as C functions. Compatibility with Gandiva’s type system is crucial.</p>
<section id="c-function-signature">
<h4>C Function Signature<a class="headerlink" href="#c-function-signature" title="Permalink to this heading">#</a></h4>
<section id="signature-mapping">
<h5>Signature Mapping<a class="headerlink" href="#signature-mapping" title="Permalink to this heading">#</a></h5>
<p>Not all Arrow data types are supported in Gandiva. The following table lists the mapping between Gandiva external function signature types and the C function signature types:</p>
<table class="table">
<thead>
<tr class="row-odd"><th class="head"><p>Gandiva type (arrow data type)</p></th>
<th class="head"><p>C function type</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>int8</p></td>
<td><p>int8_t</p></td>
</tr>
<tr class="row-odd"><td><p>int16</p></td>
<td><p>int16_t</p></td>
</tr>
<tr class="row-even"><td><p>int32</p></td>
<td><p>int32_t</p></td>
</tr>
<tr class="row-odd"><td><p>int64</p></td>
<td><p>int64_t</p></td>
</tr>
<tr class="row-even"><td><p>uint8</p></td>
<td><p>uint8_t</p></td>
</tr>
<tr class="row-odd"><td><p>uint16</p></td>
<td><p>uint16_t</p></td>
</tr>
<tr class="row-even"><td><p>uint32</p></td>
<td><p>uint32_t</p></td>
</tr>
<tr class="row-odd"><td><p>uint64</p></td>
<td><p>uint64_t</p></td>
</tr>
<tr class="row-even"><td><p>float32</p></td>
<td><p>float</p></td>
</tr>
<tr class="row-odd"><td><p>float64</p></td>
<td><p>double</p></td>
</tr>
<tr class="row-even"><td><p>boolean</p></td>
<td><p>bool</p></td>
</tr>
<tr class="row-odd"><td><p>date32</p></td>
<td><p>int32_t</p></td>
</tr>
<tr class="row-even"><td><p>date64</p></td>
<td><p>int64_t</p></td>
</tr>
<tr class="row-odd"><td><p>timestamp</p></td>
<td><p>int64_t</p></td>
</tr>
<tr class="row-even"><td><p>time32</p></td>
<td><p>int32_t</p></td>
</tr>
<tr class="row-odd"><td><p>time64</p></td>
<td><p>int64_t</p></td>
</tr>
<tr class="row-even"><td><p>interval_month</p></td>
<td><p>int32_t</p></td>
</tr>
<tr class="row-odd"><td><p>interval_day_time</p></td>
<td><p>int64_t</p></td>
</tr>
<tr class="row-even"><td><p>utf8 (as parameter type)</p></td>
<td><p>const char*,
uint32_t
[see next section]</p></td>
</tr>
<tr class="row-odd"><td><p>utf8 (as return type)</p></td>
<td><p>int64_t context,
const char*,
uint32_t*
[see next section]</p></td>
</tr>
<tr class="row-even"><td><p>binary (as parameter type)</p></td>
<td><p>const char*,
uint32_t
[see next section]</p></td>
</tr>
<tr class="row-odd"><td><p>utf8 (as return type)</p></td>
<td><p>int64_t context,
const char*,
uint32_t*
[see next section]</p></td>
</tr>
</tbody>
</table>
</section>
<section id="handling-arrow-stringtype-utf8-type-and-arrow-binarytype">
<h5>Handling arrow::StringType (utf8 type) and arrow::BinaryType<a class="headerlink" href="#handling-arrow-stringtype-utf8-type-and-arrow-binarytype" title="Permalink to this heading">#</a></h5>
<p>Both <code class="docutils literal notranslate"><span class="pre">arrow::StringType</span></code> and <code class="docutils literal notranslate"><span class="pre">arrow::BinaryType</span></code> are variable-length types. And they are handled similarly in external functions. Since <code class="docutils literal notranslate"><span class="pre">arrow::StringType</span></code> (utf8 type) is more commonly used, we will use it below as the example to explain how to handle variable-length types in external functions.</p>
<p>Using <code class="docutils literal notranslate"><span class="pre">arrow::StringType</span></code> (also known as the <code class="docutils literal notranslate"><span class="pre">utf8</span></code> type) as function parameter or return value needs special handling in external functions. This section provides details on how to handle <code class="docutils literal notranslate"><span class="pre">arrow::StringType</span></code>.</p>
<p><strong>As a Parameter:</strong></p>
<p>When <code class="docutils literal notranslate"><span class="pre">arrow::StringType</span></code> is used as a parameter type in a function signature, the corresponding C function should be defined to accept two parameters:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">char*</span></code>: This parameter serves as a pointer to the string data.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">uint32_t</span></code>: This parameter represents the length of the string data.</p></li>
</ul>
<p><strong>As a Return Type:</strong></p>
<p>When <code class="docutils literal notranslate"><span class="pre">arrow::StringType</span></code> (<code class="docutils literal notranslate"><span class="pre">utf8</span></code> type) is used as the return type in a function signature, several specific considerations apply:</p>
<ol class="arabic simple">
<li><p><strong>NativeFunction Metadata Flag:</strong>
* The <code class="docutils literal notranslate"><span class="pre">NativeFunction</span></code> metadata for this function must include the <code class="docutils literal notranslate"><span class="pre">NativeFunction::kNeedsContext</span></code> flag. This flag is critical for ensuring proper context management in the function.</p></li>
<li><dl class="simple">
<dt><strong>Function Parameters:</strong></dt><dd><ul class="simple">
<li><p><strong>Context Parameter</strong>: The C function should begin with an additional parameter, <code class="docutils literal notranslate"><span class="pre">int64_t</span> <span class="pre">context</span></code>. This parameter is crucial for context management within the function.</p></li>
<li><p><strong>String Length Output Parameter</strong>: The function should also include a <code class="docutils literal notranslate"><span class="pre">uint32_t*</span></code> parameter at the end. This output parameter will store the length of the returned string data.</p></li>
</ul>
</dd>
</dl>
</li>
<li><p><strong>Return Value</strong>: The function should return a <code class="docutils literal notranslate"><span class="pre">const</span> <span class="pre">char*</span></code> pointer, pointing to the string data.</p></li>
<li><p><strong>Function Implementation:</strong>
* <strong>Memory Allocation and Error Messaging:</strong> Within the function’s implementation, use <code class="docutils literal notranslate"><span class="pre">gdv_fn_context_arena_malloc</span></code> and <code class="docutils literal notranslate"><span class="pre">gdv_fn_context_set_error_msg</span></code> for memory allocation and error messaging, respectively. Both functions take <code class="docutils literal notranslate"><span class="pre">int64_t</span> <span class="pre">context</span></code> as their first parameter, facilitating efficient context utilization.</p></li>
</ol>
</section>
</section>
</section>
<section id="external-c-function-registration-apis">
<h3>External C function registration APIs<a class="headerlink" href="#external-c-function-registration-apis" title="Permalink to this heading">#</a></h3>
<p>You can use <code class="docutils literal notranslate"><span class="pre">gandiva::FunctionRegistry</span></code>’s APIs to register external C functions:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="c1">/// \brief register a C function into the function registry</span>
<span class="c1">/// @param func the registered function&#39;s metadata</span>
<span class="c1">/// @param c_function_ptr the function pointer to the</span>
<span class="c1">/// registered function&#39;s implementation</span>
<span class="c1">/// @param function_holder_maker this will be used as the function holder if the</span>
<span class="c1">/// function requires a function holder</span>
<span class="n">arrow</span><span class="o">::</span><span class="n">Status</span><span class="w"> </span><span class="nf">Register</span><span class="p">(</span>
<span class="w"> </span><span class="n">NativeFunction</span><span class="w"> </span><span class="n">func</span><span class="p">,</span><span class="w"> </span><span class="kt">void</span><span class="o">*</span><span class="w"> </span><span class="n">c_function_ptr</span><span class="p">,</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="n">FunctionHolderMaker</span><span class="o">&gt;</span><span class="w"> </span><span class="n">function_holder_maker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">nullopt</span><span class="p">);</span>
</pre></div>
</div>
<p>The above API allows you to register an external C function.</p>
<ul class="simple">
<li><p>The <code class="docutils literal notranslate"><span class="pre">NativeFunction</span></code> object describes the metadata of the external C function.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">c_function_ptr</span></code> is the function pointer to the external C function’s implementation.</p></li>
<li><p>The optional <code class="docutils literal notranslate"><span class="pre">function_holder_maker</span></code> is used to create a function holder for the external C function if the external C function requires a function holder. Check out the <code class="docutils literal notranslate"><span class="pre">gandiva::FunctionHolder</span></code> class and its several sub-classes for more details.</p></li>
</ul>
</section>
<section id="external-ir-functions">
<h3>External IR functions<a class="headerlink" href="#external-ir-functions" title="Permalink to this heading">#</a></h3>
<section id="ir-function-implementation">
<h4>IR function implementation<a class="headerlink" href="#ir-function-implementation" title="Permalink to this heading">#</a></h4>
<p>Gandiva’s support for IR (Intermediate Representation) functions provides the flexibility to implement these functions in various programming languages, depending on your specific needs.</p>
<section id="examples-and-tools-for-compilation">
<h5>Examples and Tools for Compilation<a class="headerlink" href="#examples-and-tools-for-compilation" title="Permalink to this heading">#</a></h5>
<ol class="arabic simple">
<li><p><strong>Using C++ or C:</strong></p>
<ul class="simple">
<li><p>If your IR functions are implemented in C++ or C, they can be compiled into LLVM bitcode, which is the intermediate representation understood by Gandiva.</p></li>
<li><p>Compilation with Clang: For C++ implementations, you can utilize clang with the <code class="docutils literal notranslate"><span class="pre">-emit-llvm</span></code> option. This approach compiles your IR functions directly into LLVM bitcode, making them ready for integration with Gandiva.</p></li>
</ul>
</li>
<li><p><strong>Integrating with CMake:</strong></p>
<ul class="simple">
<li><p>In projects where C++ is used alongside CMake, consider leveraging the <code class="docutils literal notranslate"><span class="pre">GandivaAddBitcode.cmake</span></code> module from the Arrow repository. This module can streamline the process of adding your custom bitcode to Gandiva.</p></li>
</ul>
</li>
</ol>
</section>
<section id="consistency-in-parameter-and-return-types">
<h5>Consistency in Parameter and Return Types<a class="headerlink" href="#consistency-in-parameter-and-return-types" title="Permalink to this heading">#</a></h5>
<p>It is important to maintain consistency with the parameter and return types as established in C functions. Adhering to the rules discussed in the previous section ensures compatibility with Gandiva’s type system.</p>
</section>
</section>
<section id="registering-external-ir-functions-in-gandiva">
<h4>Registering External IR Functions in Gandiva<a class="headerlink" href="#registering-external-ir-functions-in-gandiva" title="Permalink to this heading">#</a></h4>
<ol class="arabic">
<li><p><strong>Post-Implementation and Compilation:</strong></p>
<p>After successfully implementing and compiling your IR functions into LLVM bitcode, the next critical step is their registration within Gandiva.</p>
</li>
<li><p><strong>Utilizing Gandiva’s FunctionRegistry APIs:</strong></p>
<p>Gandiva offers specific APIs within the <code class="docutils literal notranslate"><span class="pre">gandiva::FunctionRegistry</span></code> class to facilitate this registration process.</p>
<p><strong>Registration APIs</strong></p>
<ul>
<li><p>Registering from a Bitcode File:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="c1">// Registers a set of functions from a specified bitcode file</span>
<span class="n">arrow</span><span class="o">::</span><span class="n">Status</span><span class="w"> </span><span class="nf">Register</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">NativeFunction</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">funcs</span><span class="p">,</span>
<span class="w"> </span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span><span class="w"> </span><span class="n">bitcode_path</span><span class="p">);</span>
</pre></div>
</div>
</li>
<li><p>Registering from a Bitcode Buffer:</p>
<div class="highlight-cpp notranslate"><div class="highlight"><pre><span></span><span class="c1">// Registers a set of functions from a bitcode buffer</span>
<span class="n">arrow</span><span class="o">::</span><span class="n">Status</span><span class="w"> </span><span class="nf">Register</span><span class="p">(</span><span class="k">const</span><span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">NativeFunction</span><span class="o">&gt;&amp;</span><span class="w"> </span><span class="n">funcs</span><span class="p">,</span>
<span class="w"> </span><span class="n">std</span><span class="o">::</span><span class="n">shared_ptr</span><span class="o">&lt;</span><span class="n">arrow</span><span class="o">::</span><span class="n">Buffer</span><span class="o">&gt;</span><span class="w"> </span><span class="n">bitcode_buffer</span><span class="p">);</span>
</pre></div>
</div>
</li>
</ul>
<p><strong>Key Points</strong></p>
<ul class="simple">
<li><p>These APIs are designed to register a collection of external IR functions, either from a specified bitcode file or a preloaded bitcode buffer.</p></li>
<li><p>It is essential to ensure that the bitcode file or buffer contains the correctly compiled IR functions.</p></li>
<li><p>The <code class="docutils literal notranslate"><span class="pre">NativeFunction</span></code> instances play a crucial role in this process, serving to define the metadata for each of the external IR functions being registered.</p></li>
</ul>
</li>
</ol>
</section>
</section>
</section>
<section id="conclusion">
<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this heading">#</a></h2>
<p>This guide provides an overview and detailed steps for integrating external functions into Gandiva. It covers both C and IR functions, and their registration in Gandiva. For more complex scenarios, refer to Gandiva’s documentation and example implementations in source code.</p>
</section>
</section>
</article>
<footer class="prev-next-footer">
<div class="prev-next-area">
<a class="left-prev"
href="expr_projector_filter.html"
title="previous page">
<i class="fa-solid fa-angle-left"></i>
<div class="prev-next-info">
<p class="prev-next-subtitle">previous</p>
<p class="prev-next-title">Gandiva Expression, Projector, and Filter</p>
</div>
</a>
<a class="right-next"
href="../streaming_execution.html"
title="next page">
<div class="prev-next-info">
<p class="prev-next-subtitle">next</p>
<p class="prev-next-title">Acero: A C++ streaming execution engine</p>
</div>
<i class="fa-solid fa-angle-right"></i>
</a>
</div>
</footer>
</div>
<div class="bd-sidebar-secondary bd-toc"><div class="sidebar-secondary-items sidebar-secondary__inner">
<div class="sidebar-secondary-item">
<div
id="pst-page-navigation-heading-2"
class="page-toc tocsection onthispage">
<i class="fa-solid fa-list"></i> On this page
</div>
<nav class="bd-toc-nav page-toc" aria-labelledby="pst-page-navigation-heading-2">
<ul class="visible nav section-nav flex-column">
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#introduction">Introduction</a></li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#overview-of-external-function-types-in-gandiva">Overview of External Function Types in Gandiva</a><ul class="visible nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#choosing-the-right-type-of-external-function-for-your-needs">Choosing the Right Type of External Function for Your Needs</a></li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#external-function-registration">External function registration</a><ul class="visible nav section-nav flex-column">
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#metadata-registration-using-the-nativefunction-class">Metadata Registration Using the <code class="docutils literal notranslate"><span class="pre">NativeFunction</span></code> Class</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#external-c-functions">External C functions</a><ul class="nav section-nav flex-column">
<li class="toc-h4 nav-item toc-entry"><a class="reference internal nav-link" href="#c-function-signature">C Function Signature</a><ul class="nav section-nav flex-column">
<li class="toc-h5 nav-item toc-entry"><a class="reference internal nav-link" href="#signature-mapping">Signature Mapping</a></li>
<li class="toc-h5 nav-item toc-entry"><a class="reference internal nav-link" href="#handling-arrow-stringtype-utf8-type-and-arrow-binarytype">Handling arrow::StringType (utf8 type) and arrow::BinaryType</a></li>
</ul>
</li>
</ul>
</li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#external-c-function-registration-apis">External C function registration APIs</a></li>
<li class="toc-h3 nav-item toc-entry"><a class="reference internal nav-link" href="#external-ir-functions">External IR functions</a><ul class="nav section-nav flex-column">
<li class="toc-h4 nav-item toc-entry"><a class="reference internal nav-link" href="#ir-function-implementation">IR function implementation</a><ul class="nav section-nav flex-column">
<li class="toc-h5 nav-item toc-entry"><a class="reference internal nav-link" href="#examples-and-tools-for-compilation">Examples and Tools for Compilation</a></li>
<li class="toc-h5 nav-item toc-entry"><a class="reference internal nav-link" href="#consistency-in-parameter-and-return-types">Consistency in Parameter and Return Types</a></li>
</ul>
</li>
<li class="toc-h4 nav-item toc-entry"><a class="reference internal nav-link" href="#registering-external-ir-functions-in-gandiva">Registering External IR Functions in Gandiva</a></li>
</ul>
</li>
</ul>
</li>
<li class="toc-h2 nav-item toc-entry"><a class="reference internal nav-link" href="#conclusion">Conclusion</a></li>
</ul>
</nav></div>
<div class="sidebar-secondary-item">
<div class="tocsection editthispage">
<a href="https://github.com/apache/arrow/edit/main/docs/source/cpp/gandiva/external_func.rst">
<i class="fa-solid fa-pencil"></i>
Edit on GitHub
</a>
</div>
</div>
</div></div>
</div>
<footer class="bd-footer-content">
</footer>
</main>
</div>
</div>
<!-- Scripts loaded after <body> so the DOM is not blocked -->
<script src="../../_static/scripts/bootstrap.js?digest=8d27b9dea8ad943066ae"></script>
<script src="../../_static/scripts/pydata-sphinx-theme.js?digest=8d27b9dea8ad943066ae"></script>
<footer class="bd-footer">
<div class="bd-footer__inner bd-page-width">
<div class="footer-items__start">
<div class="footer-item">
<p class="copyright">
© Copyright 2016-2024 Apache Software Foundation.
Apache Arrow, Arrow, Apache, the Apache feather logo, and the Apache Arrow project logo are either registered trademarks or trademarks of The Apache Software Foundation in the United States and other countries.
<br/>
</p>
</div>
<div class="footer-item">
<p class="sphinx-version">
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 6.2.0.
<br/>
</p>
</div>
</div>
<div class="footer-items__end">
<div class="footer-item">
<p class="theme-version">
Built with the <a href="https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html">PyData Sphinx Theme</a> 0.15.2.
</p></div>
</div>
</div>
</footer>
</body>
</html>