Skip to content

The C++ Abstraction Layer

fschopp edited this page Apr 15, 2011 · 9 revisions

Preamble

The MADlib C++ Abstraction Layer provides a means for writing platform-independent user-defined functions in C++. It provides a complete abstraction, performs all necessary type checking and embraces the Armadillo C++ library for providing an intuitive and clean interface to high-performance linear-algebra functions (LAPACK).

Example:

AnyValue student_t_cdf(AbstractDBInterface &db, AnyValue args) {
    AnyValue::iterator arg(args);

    // Arguments from SQL call
    const int64_t nu = *arg++;
    const double t = *arg;
    
    /* We want to ensure nu > 0 */
    if (nu <= 0)
        throw std::domain_error("Student-t distribution undefined for "
            "degree of freedom <= 0");

    return studentT_cdf(nu, t);    
}

Features

  • Performs type checking of function argument
    • Lossless conversion of pass-by-value is done implicitly (e.g., from uint32_t to uint64_t)
    • Implicit lossy conversion will throw an exception (e.g., from uint64_t to uint32_t)
  • Supports pass-by-reference (for performance reasons). However, if the user code asks for a mutable object and but the database prohibits direct modification, a copy is automatically created.
  • The only means for user code to communicate with the DBMS backend is through the interface provided by AbstractDBInterface/AbstractAllocator

Interesting PostgreSQL Implementation Details

  • Overloads the global throw/nothrow variants of operator new and operator delete to use palloc/pfree
  • All memory allocation is funneled through the PGAllocator class
  • All callbacks into the backend (in particular palloc/pfree) occur within PG_TRY/PG_CATCH blocks. This ensures that any postgres exception raised by ereport will return back to the calling C++ function. There we throw a C++ exception, which is caught at just above the C/C++ boundary. From there the PostgreSQL exception is rethrown. This procedure ensures that the C++ stack is always unwinded properly (otherwise the longjump done by ereport would lead to behavior that is undefined by the C++ standard).

Clone this wiki locally