Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > 71d40963b505df4524269198e237b3e3 > files > 68

virtuoso-opensource-doc-6.1.4-2.fc14.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
 <head profile="http://internetalchemy.org/2003/02/profile">
  <link rel="foaf" type="application/rdf+xml" title="FOAF" href="http://www.openlinksw.com/dataspace/uda/about.rdf" />
  <link rel="schema.dc" href="http://purl.org/dc/elements/1.1/" />
  <meta name="dc.title" content="16. Runtime Hosting" />
  <meta name="dc.subject" content="16. Runtime Hosting" />
  <meta name="dc.creator" content="OpenLink Software Documentation Team ;&#10;" />
  <meta name="dc.copyright" content="OpenLink Software, 1999 - 2009" />
  <link rel="top" href="index.html" title="OpenLink Virtuoso Universal Server: Documentation" />
  <link rel="search" href="/doc/adv_search.vspx" title="Search OpenLink Virtuoso Universal Server: Documentation" />
  <link rel="parent" href="runtimehosting.html" title="Chapter Contents" />
  <link rel="prev" href="javaextvm.html" title="Embedded Java VM API" />
  <link rel="next" href="vseplugins.html" title="VSEI Plugins" />
  <link rel="shortcut icon" href="../images/misc/favicon.ico" type="image/x-icon" />
  <link rel="stylesheet" type="text/css" href="doc.css" />
  <link rel="stylesheet" type="text/css" href="/doc/translation.css" />
  <title>16. Runtime Hosting</title>
  <meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" />
  <meta name="author" content="OpenLink Software Documentation Team ;&#10;" />
  <meta name="copyright" content="OpenLink Software, 1999 - 2009" />
  <meta name="keywords" content="" />
  <meta name="GENERATOR" content="OpenLink XSLT Team" />
 </head>
 <body>
  <div id="header">
    <a name="cinterface" />
    <img src="../images/misc/logo.jpg" alt="" />
    <h1>16. Runtime Hosting</h1>
  </div>
  <div id="navbartop">
   <div>
      <a class="link" href="runtimehosting.html">Chapter Contents</a> | <a class="link" href="javaextvm.html" title="Embedded Java VM API">Prev</a> | <a class="link" href="vseplugins.html" title="VSEI Plugins">Next</a>
   </div>
  </div>
  <div id="currenttoc">
   <form method="post" action="/doc/adv_search.vspx">
    <div class="search">Keyword Search: <br />
        <input type="text" name="q" /> <input type="submit" name="go" value="Go" />
    </div>
   </form>
   <div>
      <a href="http://www.openlinksw.com/">www.openlinksw.com</a>
   </div>
   <div>
      <a href="http://docs.openlinksw.com/">docs.openlinksw.com</a>
   </div>
    <br />
   <div>
      <a href="index.html">Book Home</a>
   </div>
    <br />
   <div>
      <a href="contents.html">Contents</a>
   </div>
   <div>
      <a href="preface.html">Preface</a>
   </div>
    <br />
   <div class="selected">
      <a href="runtimehosting.html">Runtime Hosting</a>
   </div>
    <br />
   <div>
      <a href="rthactivation.html">Runtime Environments</a>
   </div>
   <div>
      <a href="rthclr.html">CLR, .Net &amp; ASPX Host</a>
   </div>
   <div>
      <a href="rthclrmono.html">CLR &amp; Mono</a>
   </div>
   <div>
      <a href="javaextvm.html">Embedded Java VM API</a>
   </div>
   <div class="selected">
      <a href="cinterface.html">Virtuoso Server Extension Interface (VSEI) (C Interface)</a>
    <div>
        <a href="#writingsqlcallablecfuncs" title="Virtuoso Server Extension Interface (VSEI)">Virtuoso Server Extension Interface (VSEI)</a>
        <a href="#sqlruntimeobjects" title="SQL Run Time Objects">SQL Run Time Objects</a>
        <a href="#memmanrules" title="Memory Management Rules">Memory Management Rules</a>
        <a href="#servermainfunction" title="Server Main Function">Server Main Function</a>
        <a href="#compilingandlinking" title="Compiling &amp; Linking">Compiling &amp; Linking</a>
        <a href="#funcsbycat" title="Functions by Category">Functions by Category</a>
        <a href="#bifdefs" title="VSEI Definition">VSEI Definition</a>
        <a href="#sqlexception" title="SQL Exceptions">SQL Exceptions</a>
        <a href="#execingsql" title="Executing SQL">Executing SQL</a>
        <a href="#langfuncapi" title="Adding New Languages And Encodings Into Virtuoso">Adding New Languages And Encodings Into Virtuoso</a>
    </div>
   </div>
   <div>
      <a href="vseplugins.html">VSEI Plugins</a>
   </div>
    <br />
  </div>
  <div id="text">
<a name="cinterface" />
    <h2>16.5. Virtuoso Server Extension Interface (VSEI) (C Interface)</h2>


	<a name="writingsqlcallablecfuncs" />
    <h3>16.5.1. Virtuoso Server Extension Interface (VSEI)</h3>

	<p>The Virtuoso Server Extension Interface allows Virtuoso functionality
  to be extended by including new functions written in other languages
  such as C.  These new functions are SQL callable.</p>

  <p>These functions share the same C prototype and use
  Virtuoso internal APIs to do the following:</p>

<ul>
      <li>Retrieve arguments.</li>
      <li>Assign values to output parameters.</li>
      <li>Compile and execute SQL/PL statements and fetch results.</li>
      <li>Signal SQL errors.</li>
      <li>Return values.</li>
    </ul>

	<p>A SQL-callable C function is called a Virtuoso Server Extension (VSE).
  These are external functions integrated into Virtuoso by linking their executable
  produced with a Virtuoso server in library format, rather than executable.
  VSEs were formally known as BIFs, which stood for Built-In Functions.
  Such functions must be exported using the <span class="computeroutput">bif_define()</span>
  or <span class="computeroutput">bif_define_typed()</span> C-functions when initializing the
  extended Virtuoso server.</p>

  <p>These functions will thereafter be invoked on server threads. The
  functions should be re-entrant and comply to some simple memory management
  conventions outlined below.</p>
	<p>
These functions may execute arbitrary C code and call arbitrary APIs,
to the extent these are compatible with the host operating system&#39;s threading model.
</p>
	<p>
Virtuoso VSEs can be debugged within the normal C debugger by either
starting Virtuoso under the debugger in foreground mode or by attaching the
debugger to a running process.
</p>
	<p>
Stack consumption should not be excessive: threads normally have 100K of stack
on 32 bit platforms.  The stack size may however be increased by settings in the virtuoso.ini file.
</p>
<br />


	<a name="sqlruntimeobjects" />
    <h3>16.5.2. SQL Run Time Objects</h3>

	<p>
The Virtuoso Server Extension API introduces the following data types:
</p>

<table class="varlist">
    <tr>
        <td align="right" valign="top" class="varterm" nowrap="nowrap">box:</td>
        <td>
This is a run-time-typed block of memory which represents any SQL data type,
e.g.  number, string, array etc. Boxes have a type and length that are retrievable at run time
and can be allocated, freed and otherwise manipulated by functions appropriate to each type of box.
Boxes may form trees through use of heterogeneous arrays but should not form graphs.
</td>
    </tr>
    <tr>
        <td align="right" valign="top" class="varterm" nowrap="nowrap">query_t:</td>
        <td>This is a compiled query, corresponding to a SQL statement or procedure compilation.
The query_t is made from a SQL string and can thereafter be executed multiple times.
This is a read-only object, not affected by execution on any number of threads, analogously
to machine code not being affected by being executed.
</td>
    </tr>
    <tr>
        <td align="right" valign="top" class="varterm" nowrap="nowrap">query_instance_t:</td>
        <td>This is a structure representing a query execution state. These are
created when executing a query_t. This is analogous to
a stack frame of a C function.  It holds all relevant query state, such as
cursor positions, intermediate results, column values etc. This is passed to all
VSEs so they can have access to environment information such as current
transaction, current client etc. The query instance references the
query_t.  As a rule, the query instance is specific to a thread.
A query instance can be relatively long lived in the case of a cursor, which may
live across multiple client-server message exchanges.</td>
    </tr>
    <tr>
        <td align="right" valign="top" class="varterm" nowrap="nowrap">state_slot_t:</td>
        <td>This is a part of query_t that specifies or describes
a query time variable, column, parameter, intermediate result etc.  This is
analogous to an offset in a stack frame, it actually indexes a position inside a
query instance. Given the state slot and the instance, it is possible
to read or to set a value in the query state. Arguments of VSEs are passed as an
array of state.  Slots combined with the running query instance give the
arguments values, and can be used to set output parameters.</td>
    </tr>
    <tr>
        <td align="right" valign="top" class="varterm" nowrap="nowrap">local_cursor_t:</td>
        <td>When executing a select statement, the local cursor structure is
returned for accessing the result set rows. This is always a forward-only cursor.
This can be advanced, column values may be accessed and the cursor may be closed.</td>
    </tr>
    </table>
<br />


<a name="memmanrules" />
    <h3>16.5.3. Memory Management Rules</h3>

<p>
All state slots in a query have distinct values.  With the exception of a reference
parameter, no value is referenced twice.  All state slot values can therefore be
recursively freed independently of each other.
</p>
<p>
If a VSE returns data, this data must always be new, i.e. allocated inside the
VSE and may not be a copy of or include any of the arguments as a substructure.
All return values and arguments must be legitimate boxes and may not share a structure.
</p>
<br />


<a name="servermainfunction" />
    <h3>16.5.4. Server Main Function</h3>

<p>
The server main function for a customized Virtuoso server has the following format:
</p>

<div>
      <pre class="programlisting">
static void (*old_ddl_hook) (client_connection_t *cli) = NULL;

static void
ddl_hook (client_connection_t *cli)
{
  if (old_ddl_hook)
    old_ddl_hook (cli);

  /* DDL code (depending on the server being fully initialized
    (ex: create table) ) goes here */
}

static void
init_func (void)
{
  old_ddl_hook = set_ddl_init_hook (ddl_hook);
  /* initialization code (prerequisite for server initialization
     (bif_define, unrelated init code) goes here */
}

int
main (int argc, char *argv[])
{
  VirtuosoServerSetInitHook (init_func);
  return VirtuosoServerMain (argc, argv);
}
</pre>
    </div>

<p>
There are three phases to custom code initialization:
</p>

<ul>
      <li>execution of the main() function</li>
      <li>execution of the init_func() function</li>
      <li>execution of the ddl_hook() function</li>
    </ul>

<p>The <span class="computeroutput">init_func()</span> function is called before any server
initialization functions are called.  This is typically a place for defining new VSEs,
allocation of synchronization objects (since the server does not have any threads yet),
and/or custom code initialization not related to Virtuoso.  Here, the
<span class="computeroutput">set_ddl_init_hook()</span> should be called also, if it exists,
to register the <span class="computeroutput">ddl_hook()</span> callback function.
</p>
<div class="note">
      <div class="notetitle">Note:</div>
<p>The <span class="computeroutput">old_ddl_hook()</span> mechanism -
this allows queuing of the ddl_hooks.</p>
    </div>

<p>The <span class="computeroutput">ddl_hook()</span> function is called during normal
startup just before the roll forward, but after the server&#39;s internal structure has
been initialized.  This is typically a place to execute SQL statements to initialize
the extension.  The variable <span class="computeroutput">client_connection_t *</span>
is passed to the function to provide the client connection that should
be used for SQL execution.</p>

<p>The <span class="computeroutput">main()</span> function can call
<span class="computeroutput">VirtuosoServerSetInitHook()</span> if there is any
Virtuoso-related initialization to be performed, and should then call the
<span class="computeroutput">VirtuosoServerMain()</span> function to start the
Virtuoso server.  The <span class="computeroutput">VirtuosoServerMain()</span> function
will return control after the server has been shut down.</p>
<br />


<a name="compilingandlinking" />
    <h3>16.5.5. Compiling &amp; Linking</h3>

<p>
The files should be compiled for the multi-threaded environment appropriate to the
operating system and should be linked accordingly e.g.
<span class="computeroutput">-lm</span>, <span class="computeroutput">-ldl</span>.</p>

<p>The Virtuoso distribution contains the following libraries/object files:</p>

<ul>
 <li>
     <div class="formalpara">
          <strong>libvirtuoso-* libraries/object files</strong>
  <p>The Virtuoso engine.  The suffix denotes the kind of remote and threading
  support : -iodbc for iODBC, -udbc for UDBC, -t for native threads, -f for fiber
  threads.</p>
     </div>
      </li>

 <li>
     <div class="formalpara">
          <strong>c_javavm object file</strong>
  <p>the Virtuoso Java VM Integration file (no main function). This is the
  file to be linked in if the custom code executable needs to have Java VM
  support. To initialize the Java VM integration the C function
  <span class="computeroutput">void bif_init_func_javavm (void)</span> should be called from the
  <span class="computeroutput">VirtuosoServerSetInitHook</span> hook.  This file references
  the <span class="computeroutput">libjvm</span> library from the Java JRE, hence,
  should also be appended to your linker options.</p>
     </div>
      </li>

 <li>
     <div class="formalpara">
          <strong>c_bif_server_php object file</strong>
  <p>The Virtuoso PHP integration support library.  This is the file to be
  linked in if the custom code executable needs to have the PHP support built
  in.  To initialize the PHP engine integration the C++ function
  <span class="computeroutput">void init_func_php (void)</span> should be called from
  the <span class="computeroutput">VirtuosoServerSetInitHook</span> hook.  Note that this file
  is a C++ object file and needs to be linked in accordingly.  This file
  references the libphp4 library.</p>
     </div>
      </li>

 <li>
     <div class="formalpara">
          <strong>basec object file</strong>
  <p>The Virtuoso .NET CLR Integration file.  This is the file to be linked
  in if the custom code executable needs to have the .NET CLR integration built
  in.  This is a C file.</p>
     </div>
      </li>

 <li>
     <div class="formalpara">
          <strong>c_dotnet object file</strong>
  <p>The Virtuoso .NET CLR Integration file.  This is the file to be linked in
  if the custom code executable needs to have the .NET CLR integration
  (and nothing but) built in.  This is a C++ file.  Binaries using this file
  should initialize the .NET CLR support by calling the C++ function
  <span class="computeroutput">void bif_init_func_clr (void)</span> (defined in the basec object
  file) from the <span class="computeroutput">VirtuosoServerSetInitHook</span> hook.  In order
  for the .NET CLR support to work correctly the
  <span class="computeroutput">::CoInitialize</span> Win32 COM API should also be
  called before the <span class="computeroutput">VirtuosoServerMain</span> call.</p>
     </div>
      </li>

 <li>
     <div class="formalpara">
          <strong>sql_code_javavm object file</strong>
  <p>This contains the DDL definitions for the Java VM support.  Executables
  using that binary should call the <span class="computeroutput">sqls_define_javavm</span>
  function in their DDL init hook.</p>
     </div>
      </li>

 <li>
        <div class="formalpara">
          <strong>sql_code_xslt object file</strong>
  <p>This contains the DDL definitions of the XSLT stylesheets used in the
  Java VM &amp; CLI support.  Executables using that binary should call the
  <span class="computeroutput">sqls_define_xslt</span> function in their DDL init hook.</p>
  </div>
      </li>

 <li>
     <div class="formalpara">
          <strong>sql_code_clr object file</strong>
  <p>This contains the DDL definitions for the .NET CLR integration support.
  Executables using that binary should call the <span class="computeroutput">sqls_define_clr</span>
  function in their DDL init hook.</p>
     </div>
      </li>

</ul>
<br />


<a name="funcsbycat" />
    <h3>16.5.6. Functions by Category</h3>


<a name="genboxfuncs" />
    <h4>16.5.6.1. General Box Functions</h4>

<p>The box, usually marked with the caddr_t data type is the basic representation
of any SQL data in Virtuoso.  All boxes have a run time data type, with a name
beginning with <span class="computeroutput">DV_</span>.  All boxes have a 3 byte
run time length which allows for up to 16 MB of contiguous array size in SQL data.</p>

<p>The further interpretation of the content of the box is determined by the
type tag.  The length is always an exact byte length, although the actual length
is rounded up to the next suitably aligned value.  The length and tag of a box
must never be changed while the box is allocated but the content is freely
writable.  The tag and length reside immediately under the pointer of the box,
so that a box, with the appropriate type cast will pass as a C array or string.</p>

<p>Numbers are generally represented as boxes.  There is an exception for
small integers, which are always distinguishable from pointers.  Thus the range
from -10000 to 10000 are not allocated as boxes holding the value but can be
passed directly.  This is hidden however and the programmer need not be
concerned about this except sometimes when debugging.</p>

<p>The byte order in boxes depends on the platform.</p>

<p>The most important types are:</p>

	<ul>
      <li>
        <strong>DV_SHORT_STRING</strong> -  The box contains a null
    terminated string of char. The box length is 1 + the count of characters,
    including the final 0 in the count.</li>
      <li>
        <strong>DV_LONG_STRING</strong> - same as DV_SHORT_STRING.</li>
      <li>
        <strong>DV_LONG_INT, TAG_BOX</strong> - The box is sizeof (long)
    long, with the long as element 0, in the appropriate byte order.</li>
      <li>
        <strong>DV_SINGLE_FLOAT</strong> - sizeof (float) bytes,
    containing the float.</li>
      <li>
        <strong>DV_DOUBLE_FLOAT</strong> - sizeof (double) bytes,
    contains the double.</li>
      <li>
        <strong>DV_NUMERIC</strong> - opaque, contains a decimal floating
    point. The numeric_t functions can be used, see
    appropriate documentation.</li>
      <li>
        <strong>DV_BIN</strong> - Binary string, no terminating 0
    counted in the length.</li>
      <li>
        <strong>DV_DATETIME</strong> - datetime, opaque, dt_ functions
    can be used, see appropriate documentation.</li>
      <li>
        <strong>DV_BLOB_HANDLE</strong> - Blob handle, opaque but
    convertible to string if short enough.</li>
      <li>
        <strong>DV_ARRAY_OF_POINTER</strong> - Heterogeneous array,
    sizeof (caddr_t) * n_elements, first all elements are box pointers. The
    length is in bytes, so divide by sizeof (caddr_t).</li>
      <li>
        <strong>DV_DB_NULL</strong> - a box of 0 bytes (header only),
    represents the SQL NULL value.</li>
    </ul>
<br />


<a name="boxfunctions" />
    <h4>16.5.6.2. Box Functions</h4>

      
        <span class="funcdef">box_t <span class="function">dk_alloc_box</span>
    </span>
        (<span class="paramdef">uint32 <span class="parameter">bytes</span>
    </span>, 
        <span class="paramdef">int <span class="parameter">tag</span>
    </span>);
      

<p>
      <span class="computeroutput">dk_alloc_box()</span> allocates a box of the given size
and type.  The initial contents are undefined.</p>

      
        <span class="funcdef">int <span class="function">dk_free_box</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">box</span>
    </span>);
      

<p>
      <span class="computeroutput">dk_free_box()</span> frees a box allocated by
<span class="computeroutput">dk_alloc_box()</span>.  The argument may not be any other pointer.</p>

      
        <span class="funcdef">int <span class="function">dk_free_tree</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">box</span>
    </span>);
      

<p>
      <span class="computeroutput">dk_free_tree()</span> is like <span class="computeroutput">dk_free_box()</span>
but will free recursively, following through DV_ARRAY_OF_POINTER boxes.</p>

      
        <span class="funcdef">uint32 <span class="function">box_length</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">box2</span>
    </span>);
      

<div>
      <pre class="programlisting">
#define box_tag(box) \
	(*((dtp_t *) &amp;(((unsigned char *)(box))[-1])))
</pre>
    </div>

<p>
These return the length and the tag of a box.
</p>

      
        <span class="funcdef">long <span class="function">unbox</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">n</span>
    </span>);
      

      
        <span class="funcdef">box_t <span class="function">box_num</span>
    </span>
       (<span class="paramdef">long <span class="parameter">n</span>
    </span>);
      

      
        <span class="funcdef">box_t <span class="function">box_dv_short_string</span>
    </span>
       (<span class="paramdef">char *<span class="parameter">string</span>
    </span>);
      

      
        <span class="funcdef">box_t <span class="function">box_double</span>
    </span>
       (<span class="paramdef">double <span class="parameter">d</span>
    </span>);
      

      
        <span class="funcdef">box_t <span class="function">box_float</span>
    </span>
       (<span class="paramdef">float <span class="parameter">f</span>
    </span>);
      

<div>
      <pre class="programlisting">
#define unbox_num(n) unbox(n)
#define unbox_float(f) (*((float *)f))
#define unbox_double(f) (*((double *)f))
#define unbox_string(s) ((char *)s)
</pre>
    </div>

<p>The above functions and macros convert between C data types and boxes.
<span class="computeroutput">box_dv_short_string()</span> takes a
<span class="computeroutput">char *</span> to any null terminated string and
allocates a string box of appropriate size.  This itself looks like a null
terminated string but has the box header with the run time length and type
under the pointer.</p>

      
        <span class="funcdef">box_t <span class="function">box_copy</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">box</span>
    </span>);
      

<p>
      <span class="computeroutput">box_copy()</span> returns an identical size box with the
same type and contents.</p>

      
        <span class="funcdef">box_t <span class="function">box_copy_tree</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">box</span>
    </span>);
      

<p>
      <span class="computeroutput">box_copy_tree()</span> performs a recursive copy, traversing
<span class="computeroutput">DV_ARRAY_OF_POINTER</span> references.</p>

      
        <span class="funcdef">int <span class="function">box_equal</span>
    </span>
       (<span class="paramdef">box_t <span class="parameter">b1</span>
    </span>, 
       <span class="paramdef">box_t <span class="parameter">b2</span>
    </span>);
      

<p>Given two arbitrary boxes, returns true if they are recursively equal.</p>
<br />

<a name="boxexamples" />
    <div class="example">
<div class="exampletitle">Box Examples</div>

<p>Below is the code for box_copy_tree:</p>

<div>
        <pre class="programlisting">
box_t
box_copy (box_t box)
{
  dtp_t tag;
  uint32 len;
  box_t copy;

  if (!IS_BOX_POINTER (box))
    return box;

  tag = box_tag (box);
  if (box_copier[tag])
    return (box_copier[tag] (box));
  len = box_length (box);
  copy = dk_alloc_box (len, tag);
  memcpy (copy, box, (uint32) len);
  return copy;
}
</pre>
      </div>

<div>
        <pre class="programlisting">
box_t
box_copy_tree (box_t box)
{
  box_t *copy;
  dtp_t tag;

  if (!IS_BOX_POINTER (box))
    return box;

  tag = box_tag (box);
  copy = (box_t *) box_copy (box);
  if (tag == DV_ARRAY_OF_POINTER || tag == DV_LIST_OF_POINTER)
    {
      uint32 inx, len = BOX_ELEMENTS (box);
      for (inx = 0; inx &lt; len; inx++)
	copy[inx] = box_copy_tree (((box_t *) box)[inx]);
    }

  return (box_t) copy;
}
</pre>
      </div>
</div>

<div class="note">
      <div class="notetitle">Note:</div>
<p>The <span class="computeroutput">IS_BOX_POINTER</span> check at the start will detect
the unboxed, &#39;bare&#39; small integers which are actually not allocated
and can be returned by value.  Only then can box_tag be used to find the type.</p>

<p>The DV_TYPE_OF macro should be used instead of box_tag when the type
is unknown to avoid de-referencing a small integer.</p>

<p>Also note <span class="computeroutput">BOX_ELEMENTS</span>, which is
box_length () / sizeof (caddr_t).  This is practical for iterating over arrays.</p>
</div>

<div class="tip">
      <div class="tiptitle">See Also</div>
<p>The <a href="">VSEI Functions</a>.</p>
    </div>

<br />



<a name="bifdefs" />
    <h3>16.5.7. VSEI Definition</h3>

<div>
      <pre class="programlisting">
typedef caddr_t (*bif_t) (caddr_t *qst, caddr_t *error_return, state_slot_t ** arguments);
void bif_define (char *name, bif_t bif);
void bif_define_typed (char * name, bif_t bif, bif_type_t *bt);
</pre>
    </div>

<p>
These functions associate a function pointer to a VSE name.
The typed variant allows associating a value type used when inferring SQL
meta-data if the result is returned to a client.  The type can be one of the
following externs:</p>

<ul>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_varchar;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_any;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_integer;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_double;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_float;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_numeric;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_convert;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_timestamp;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_time;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_date;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_datetime;</span>);</li>
      <li>(<span class="paramdef">extern <span class="parameter">bif_type_t</span> bt_bin;</span>);</li>
    </ul>

<p>If a VSE accesses indexes either by its own internal code or by executing
Virtuoso/PL statements, there becomes a potential for deadlocks.  To prevent
deadlocks, the Virtuoso/PL compiler must be informed of potential index usage inside
the VSE.  Special deadlock-safe code can be created for its needs.  The
<span class="computeroutput">bif_set_uses_index()</span> function should be used after
<span class="computeroutput">bif_define()</span> or <span class="computeroutput">bif_define_typed()</span>
in such cases.</p>



<p>The potential for deadlocking is always present if the VSE
executes Virtuoso/PL code or uses XPath/XSLT functions.  Other functions
of Virtuoso&#39;s C interface are deadlock-safe since they perform no database access.</p>
<br />


<a name="sqlexception" />
    <h3>16.5.8. SQL Exceptions</h3>

<div>
      <pre class="programlisting">
caddr_t srv_make_error (char *code, char *msg);
void sqlr_error (char *code, char *msg,...);
void sqlr_resignal (caddr_t err);
</pre>
    </div>

	<p>
An error object is a three element array of type
<span class="computeroutput">DV_ARRAY_OF_POINTER</span>, consisting of the number
3, the SQL state and the message.
The control flow in case of errors signalled inside VSEs is a longjmp to an outer context,
typically that of the calling stored procedure or top level query.  The condition is there
handled or sent to the next level up, ultimately to the ODBC, JDBC or Web client.
Executing a SQL statement inside a VSE always returns and never exits the VSE by longjmp.
Thus the VSE gets a first look at all SQL errors caused by statements executed by it.
</p>
	<p>
sqlr_error is the normal function for signaling a SQL state.  It takes a 5 character
SQL state, a printf format string and optional arguments, a la printf.
</p>

	<p>
sqlr_resignal is used to throw a condition to the next level handler.
This is typically done when executing a query which returns an error and
the error is sent up to the caller of the VSE.
</p>
	<p>
srv_make_error makes the error structure.  The expression
</p>
	<p>
sqlr_resignal (srv_make_error (&quot;12345&quot;, &quot;message&quot;));
is equivalent to sqlr_error (&quot;12345&quot;, &quot;message&quot;);
</p>

	<div class="note">
      <div class="notetitle">Note</div>
	<p>srv_make_error does not take the printf-type arguments.</p>
</div>

	<p>
By convention a NULL pointer indicates no error.
sqlr_resignal (NULL) is an error.
</p>
	<p>
The macros:
</p>
<div>
      <pre class="programlisting">
#define ERR_STATE(err)  (((caddr_t*) err)[1])
#define ERR_MESSAGE(err)  (((caddr_t*) err)[2])
</pre>
    </div>

	<p>
can be used to read an error returned by a statement.
</p>
<br />


<a name="execingsql" />
    <h3>16.5.9. Executing SQL</h3>

<div>
      <pre class="programlisting">
query_t * sql_compile (char *string2, client_connection_t * cli,
				caddr_t * err, int store_procs);
void qr_free (query_t * qr);

client_connection_t * qi_client (caddr_t * qi);
</pre>
    </div>

	<p>
These functions allow executing SQL from VSEs.
First the SQL statement needs to be compiled with sql_compile. The statement may take
value parameters and may be a DDL or DML statement, including select, update,
procedure call, table creation etc.
</p>
	<p>
The query_t returned can be used multiple times on any number of simultaneous threads.
if an application repeatedly performs
the same queries the text can be compiled once and reused at infinitum.
</p>
	<p>
qr_free will free a query returned by sql_compile.
</p>

<a name="" />
    <div class="example">
<div class="exampletitle">Example</div>
<div>
        <pre class="programlisting">
{
  caddr_t err = NULL;
  query_t * qr  = sql_compile (&quot;select * from SYS_USERS&quot;, qi_client (qst), &amp;err, 0);
  ...
  if (err)
  exit (-1);
  qr_free (qr);
}
</pre>
      </div>
</div>

<div>
      <pre class="programlisting">
caddr_t qr_rec_exec (query_t * qr, client_connection_t * cli,
    local_cursor_t ** lc_ret, query_instance_t * caller, stmt_options_t * opts,
    long n_pars, ...);
</pre>
    </div>

	<p>
Once a query is compiled it can be executed and fetched.  This function executes
a query in the context of a VSE.  The execution is on behalf of the same
user and in the same transaction as the VSE.  This is only possible in the
context of a VSE, not at top level in the main program, for example.
</p>
	<p>
The first argument is the compiled query to execute.
The second is the client connection, obtained by qi_client from the qst argument of the VSE.
The lc_ret, if non NULL will get a be set to a newly allocated local_cursor_t * that allows
fetching rows from the result set. This only applies to a select statement.
The caller is the qst argument of the VSE,
The opts can be NULL.
The n_args is the count of query parameters, 0 if no parameters are passed.
</p>
	<p>
The return value is an error, suitable for sqlr_resignal.  A NULL value means success.
</p>
	<p>
It should be double-checked if the query access or potentially may access any tables or indexes.
If it may do this, the VSE must be described as deadlock-unsafe by
calling bif_set_uses_index() after bif_define() or bif_define_typed().
If qr_rec_exec access any tables or views, and the call of VSE from Virtuoso/PL
code is compiled as deadlock-safe, the whole server may be halted.
</p>
	<p>
If parameters are passed, a group of 3 actual parameters follows for each ? in the
query being executed.  In each such group the first is the name of the parameter, of
the form &quot;:n&quot;, where n is the position of the parameter, starting at 0, so &quot;:0&quot;
corresponds to the 1st ? and &quot;:11&quot; to the 12th.
The second in the group of 3 is the value, usually a box pointer.
The third is the type, one of QRP_INT, QRP_STRING or QRP_RAW.
</p>
	<p>
QRP_INT means that the value will be converted to a box as by box_num.
QRP_STRING means that the value will be converted to a string as by box_dv_short_string.
In either case the value is allocated and freed as part of the execution.
QRP_RAW means that an arbitrary box is passed as is.  If so, this box will be freed in the
process and MUST NOT BE REFERENCED AGAIN in the VSE.
if the statement is a select, lc_ret should be specified and should be the address of a
local_cursor_t * variable, where the cursor can be returned.
</p>
	<div>
      <pre class="programlisting">
long lc_next (local_cursor_t * lc);
caddr_t lc_nth_col (local_cursor_t * lc, int n);
void lc_free (local_cursor_t * lc);
</pre>
    </div>
	<p>
These functions allow reading through a result set.
The local_cursor_t * must have come from qr_rec_exec.
</p>
	<p>
lc_next  will move the cursor one row forward.  The first call after the exec places the cursor
on the first row. A 0 return value indicates that the cursor is at end.  if 0 is returned at the
first call, the result set had zero rows.
The data member lc_error may be set and should be checked after calls to this function.
See examples. The value will be suitable for sqlr_resignal if copied (box_copy_tree).
</p>
	<p>
The lc_nth_col returns the value of the nth column of the current row. The index is 0 based.
The value is an arbitrary box pointer and is READ ONLY, to be copied (box_copy_tree) if the
application needs to keep it around.  The value will stay readable until the next lc_next or
lc_free.  Use DV_TYPE_OF et al to determine the type of the value.
</p>
	<p>
lc_free frees the cursor and any resources associated to it.
This has no effect on the transaction.
</p>
	<p>
The bif_my_select function returns an array with one element for each row of the SYS_KEYS table.
The rows are themselves arrays containing the column values.
</p>
<br />
	
		<a name="langfuncapi" />
    <h3>16.5.10. Adding New Languages And Encodings Into Virtuoso</h3>
		<p>
There are too many languages to be able to support them all by default so
Virtuoso is user extensible in this respect.
The built-in &#39;x-any&#39; language supports most languages to a degree,
but it is not the optimum solution for some specific languages or if
you want to perform a words&#39; normalization to make text search more effective.
To make Virtuoso extensible,
language-specific functions are organized into <strong>language handlers</strong>, and handlers are
organized in hierarchical trees.  Every handler contains pointers to such functions as &quot;count
words in given string&quot;, &quot;call given callback once for every word in the string&quot; etc.</p>
		<p>
XML documents and SQL procedures may identify languages by their
names, for example by value of <strong>xml:lang</strong> attribute,
<span class="computeroutput">content_language</span> argument of
built-in functions, or by <span class="computeroutput">__lang</span> option etc...
Every language handler defines up to two names of the language it supports, one matching ISO 639
regulations (e.g. &#39;en&#39;), and one matching RFC 1766 (e.g. &#39;en-UK&#39;).
When Virtuoso finds a match to the language name specified, it searches through
the an internal hash-table.  If the name is unknown, the &#39;x-any&#39; handler
will be returned as a default.</p>

		<p>
Custom language handlers should contain a pointer to a more generic handler, e.g. to the handler,
Handler may have NULLs stored instead of pointers to required functions, these NULLs will be
replaced with pointers to generic handler&#39;s functions automatically when the custom handler will be
activated.</p>

<div class="tip">
      <div class="tiptitle">See Also:</div>
 <p>
        <a href="fn_lh_get_handler.html">lh_get_handler</a>
      </p>
 <p>
        <a href="fn_lh_load_handler.html">lh_load_handler</a>
      </p>
</div>

		<p>
There are two trees of language handlers in current version of Virtuoso. &quot;Main&quot;
tree starts from &#39;x-any&#39; root and contains handlers of languages used in documents,
another tree starts from &#39;x-ftq-x-any&#39; root contains handlers of
Free Text query (&#39;ftq&#39;) languages.  The difference is in handling of wildcard characters:
query string &#39;hello, wo*ld&#39; consists of two &quot;words&quot;, &#39;hello&#39; and &#39;wo*ld&#39;, and
&#39;x-ftq-x-any&#39; will properly locate them, but &#39;x-any&#39; handler will report three words --
&#39;hello&#39;, &#39;wo&#39; and &#39;ld&#39;, because it knows nothing about special meaning of &#39;*&#39; in query
strings.  That is why every handler may contain a pointer to a handler of its own query language.</p>

		<p>
In addition to plain language handlers, it&#39;s possible to add handlers of &quot;encoded language&quot;
They are useful if you have large number of documents in some particular encoding and speed of
free text indexing is critical for your applications.  While usual handlers deal with Unicode data,
and it requires data to be decoded before processing, functions of &quot;encoded language&quot;
handler may accept buffers of encoded text, eliminating decoding.</p>

<div class="tip">
      <div class="tiptitle">See Also:</div>
 <p>
        <a href="fn_elh_get_handler.html">elh_get_handler</a>
      </p>
 <p>
        <a href="fn_elh_load_handler.html">elh_load_handler</a>
      </p>
</div>

		<p>
The OpenLink Virtuoso Server distribution contains sources of sample language handler for &#39;en-UK&#39; language.
The difference between &#39;x-any&#39; handler and this one is in handling of abbreviations and numbers.
&#39;en-UK&#39; handler will read phrase &#39;$3.54 per sq.inch.&#39; as the sequence of words &#39;3.54&#39;, &#39;per&#39; and &#39;sq.inch&#39;,
instead of sequence &#39;54&#39;, &#39;per&#39;, &#39;sq&#39; and &#39;inch&#39; that &#39;x-any&#39; will read.  The generic &#39;x-any&#39; handler
has no specific rules for dealing with the &quot;decimal point&quot; because in many scripts
&quot;decimal comma&quot; is used, thus &#39;3.54&#39; will be processed as pair of words &#39;3&#39; and &#39;54&#39;,
but &#39;3&#39; will be ignored in many cases as noise word due to its 1-character length.</p>
		<p>
In addition to the language extension interface, Virtuoso provides an <strong>eh_load_handler</strong> function
to add new encodings, but it should be used solely for multi-character encodings which cannot be supported through
the usual Virtuoso <a href="coredbengine.html#internationalization">International Character Support</a>.
If an encoding was created by the <a href="fn_charset_define.html">CHARSET_DEFINE</a> function,
Virtuoso can build special lookup tables for very fast text translation from Unicode to the
encoding, thus you are not likely to gain in performance by writing your own C code, but some applications will
know nothing about your encoding because they will check only the SYS_CHARSETS system table.</p>
<br />
<table border="0" width="90%" id="navbarbottom">
    <tr>
        <td align="left" width="33%">
          <a href="javaextvm.html" title="Embedded Java VM API">Previous</a>
          <br />Embedded Java VM API</td>
     <td align="center" width="34%">
          <a href="runtimehosting.html">Chapter Contents</a>
     </td>
        <td align="right" width="33%">
          <a href="vseplugins.html" title="VSEI Plugins">Next</a>
          <br />VSEI Plugins</td>
    </tr>
    </table>
  </div>
  <div id="footer">
    <div>Copyright© 1999 - 2009 OpenLink Software All rights reserved.</div>
   <div id="validation">
    <a href="http://validator.w3.org/check/referer">
        <img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" />
    </a>
    <a href="http://jigsaw.w3.org/css-validator/">
        <img src="http://jigsaw.w3.org/css-validator/images/vcss" alt="Valid CSS!" height="31" width="88" />
    </a>
   </div>
  </div>
 </body>
</html>