Sophie

Sophie

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

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="10. Database Event Hooks" />
  <meta name="dc.subject" content="10. Database Event Hooks" />
  <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="hooks.html" title="Chapter Contents" />
  <link rel="prev" href="fn_dbev_prepare.html" title="SQL Statement Preparation" />
  <link rel="next" href="fn_davlogins.html" title="WebDAV Logins" />
  <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>10. Database Event Hooks</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="sqlparsetree" />
    <img src="../images/misc/logo.jpg" alt="" />
    <h1>10. Database Event Hooks</h1>
  </div>
  <div id="navbartop">
   <div>
      <a class="link" href="hooks.html">Chapter Contents</a> | <a class="link" href="fn_dbev_prepare.html" title="SQL Statement Preparation">Prev</a> | <a class="link" href="fn_davlogins.html" title="WebDAV Logins">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="hooks.html">Database Event Hooks</a>
   </div>
    <br />
   <div>
      <a href="fn_dbev_startup.html">Database Startup</a>
   </div>
   <div>
      <a href="fn_dbev_connect.html">Database Connections</a>
   </div>
   <div>
      <a href="fn_logins.html">Database Logins</a>
   </div>
   <div>
      <a href="fn_disconnect.html">Database Disconnections</a>
   </div>
   <div>
      <a href="fn_dbev_shutdown.html">Database Shutdown</a>
   </div>
   <div>
      <a href="fn_dbev_prepare.html">SQL Statement Preparation</a>
   </div>
   <div class="selected">
      <a href="sqlparsetree.html">SQL Parse Tree</a>
    <div>
        <a href="#notesonspecialparsetree" title="Notes on Special Features of the Parse Tree">Notes on Special Features of the Parse Tree</a>
        <a href="#sqlsecandparsetrees" title="SQL Security and Parse Trees">SQL Security and Parse Trees</a>
        <a href="#debuggingparsetree" title="Debugging with Parse Trees">Debugging with Parse Trees</a>
    </div>
   </div>
   <div>
      <a href="fn_davlogins.html">WebDAV Logins</a>
   </div>
   <div>
      <a href="assocauxdata.html">Associating Auxiliary Data With A Connection</a>
   </div>
    <br />
  </div>
  <div id="text">
    <a name="sqlparsetree" />
    <h2>10.7. SQL Parse Tree</h2>
  <p>
The SQL parse tree is composed of DV_ARRAY_OF_POINTER boxes.  Other types of
boxes may occur as leaves, where they are interpreted as literals.  All nodes&#39;
first element (index 0) is the type of the node, one of the constants in sqlparext.h.
</p>
  <p>
The nodes&#39; various fields can be accessed through the data members of the
sql_tree_t union.  Most data members are pointers to the same type.  Sometimes they
are double pointers, denoting a variable length array of pointers to the struct.
The caddr_t type is used to denote a terminal, like a string or other constant.
The types are only for declarative value, the entire structure is a self describing,
run time typed tree of boxes.
</p>
  <p>
The correspondence of the tree to the SQL syntax is documented by the yacc grammar
supplied as appendix.
</p>

<p>
We will next examine the need to know example:
</p>

<div>
      <pre class="programlisting">
ST *
nk_tree_and (ST* left, ST * right)
{
  if (left &amp;&amp; right)
    return ((ST*) list (4, BOP_AND, left, right, NULL));
  if (left)
    return left;
  return right;
}
</pre>
    </div>

  <p>
This function adds anAND operation between 2 sub trees.  If either is NULL, the
non-null one is returned.  The list function is used as a universal constructor of
the parse tree, where the first argument is the count of arguments to follow.
</p>
  <p>
The above could have been written as follows without list:
</p>
<div>
      <pre class="programlisting">
ST * r = (ST*) dk_alloc_box (4 * sizeof (caddr_t), DV_ARRAY_OF_POINTER);
r-&gt;type = BOP_AND;
r-&gt;_.bin_exp.left = left;
r-&gt;_.bin_exp.right = right;
r-&gt;_.bin_exp.more = NULL;
</pre>
    </div>

<p>
We see that the list notation is more concise.
</p>

<div>
      <pre class="programlisting">
void
nk_test_add (ST * outer_texp, char * corr_name, int uid)
{
  /* add a exists (select 1 from need_to_know where nk_class = &lt;corr_name&gt;.r_class) */
  ST * sel, * exists, * texp, **from;
  ST * where = (ST*) list (4, BOP_EQ, list (3, COL_DOTTED, NULL, box_string (&quot;NK_CLASS&quot;)),
			   list (3, COL_DOTTED, box_string (corr_name), box_string (&quot;R_CLASS&quot;)), NULL);
  where = nk_tree_and (where, listst (4, BOP_EQ, list (3, COL_DOTTED, NULL, box_string (&quot;NK_USER&quot;)), box_num (uid), NULL));
  from = (ST**)
    list (1, list (3, TABLE_REF,
		   list (5, TABLE_DOTTED,
			 box_string (&quot;DB.DBA.NEED_TO_KNOW&quot;),
			 NULL, box_num (0), box_num (0)),
		   NULL));
  texp = listst (7, TABLE_EXP, from,
	       where, NULL, NULL, NULL, -1);
  sel = listst (5, SELECT_STMT, NULL, list (1, box_num (1)), NULL, texp);
  exists = (ST*) list (5, EXISTS_PRED, NULL, sel, NULL, NULL);
  outer_texp-&gt;_.table_exp.where = nk_tree_and (outer_texp-&gt;_.table_exp.where, exists);
}
</pre>
    </div>

  <p>
This function takes the table expression referencing the REPORT table and the correlation
name used for the table and the user id of the querying user.  It adds the existence test for the
need to know.  The logic is self evident when examined in the context of the yacc grammar.
Note that the table in the FROM of the sub query is a TABLE_REF node with a TABLE_DOTTED
node, which finally contains the table and correlation names.  Note that all strings must
be allocated as string boxes.  This is because the tree may only reference other boxes.  Note
that all numbers except for the types of the nodes are boxed with box_num.  This will make
sure that numbers and pointers are always distinguishable.  The node types are distinguishable
by definition due to their small absolute value.
</p>

<div>
      <pre class="programlisting">
caddr_t
bif_need_to_know (caddr_t * qst, caddr_t * err_ret, state_slot_t ** args)
{
  unsigned inx;
  caddr_t uid = (caddr_t) bif_long_arg (qst, args, 0, &quot;need_to_know&quot;);
  ST * tree = (ST*) bif_array_arg (qst, args, 1, &quot;need_to_know&quot;);
  if (ST_P (tree, SELECT_STMT))
    {
      ST * texp = tree-&gt;_.select_stmt.table_exp;
      if (!texp)
	return 0; /* select w/o a from */
      for (inx = 0; inx &lt; BOX_ELEMENTS (texp-&gt;_.table_exp.from); inx++)
	{
	  ST * tref = texp-&gt;_.table_exp.from[inx];
	  if (ST_P (tref, TABLE_REF))
	    tref = tref-&gt;_.table_ref.table;
	  if (ST_P (tref, TABLE_DOTTED))
	    {
	      char * corr_name;
	      if (tref-&gt;_.table.prefix)
		corr_name = tref-&gt;_.table.prefix;
	      else
		corr_name = tref-&gt;_.table.name;
	      if (strstr (tref-&gt;_.table.name, &quot;REPORT&quot;))
		nk_test_add (texp, corr_name, (int)uid);
	    }
	}
    }
  return 0;
}
</pre>
    </div>
  <p>
This is the top level need to know function.  It first checks to see that the
statement is a select, that it has a FROM clause (table expression).
For each table in the FROM which has REPORT as part of its name the function adds an existence test
to check the user&#39;s need to know.  Note that the correlation name is taken from the
table and that the table name is used in the absence of a correlation name
to disambiguate the reference.  Note that the table_exp.from is of type
ST **, meaning a variable length array of boxes.  Note that BOX_ELEMENTS returns the length
in pointer-size units.
</p>
  <p>
Note that in this example the tree is spliced in place, only adding nodes.  There is
no need to free data or to modify the top node.
</p>

<a name="notesonspecialparsetree" />
    <h3>10.7.1. Notes on Special Features of the Parse Tree</h3>
  <p>
The parse tree structure has a 1 to 1 correspondence with the yacc grammar.  The members
of the union in sql_tree_t are mostly named after the syntactic element and the constant
that identifies them.  There are however some points worth noting:
</p>

<ul>
      <li>Literals - All boxes whose tag is not DV_ARRAY_OF_POINTER are considered literals and
may appear in all places where a literal is allowed.</li>
      <li>Identifier Case - The case conversion of identifiers is controlled by the CaseMode ini file setting.
When introducing a constant name referencing a VSE, one should use sqlp_box_id_upcase to get the right case for all modes.</li>
      <li>The identifiers, once in the tree, are compared case sensitively in all modes case modes except 2.</li>
      <li>Hook functions should use the appropriate comparison functions for the desired case sensitivity.</li>
      <li>When generating references to names the case should be correct as defined by the case mode.</li>
    </ul>
<br />

<a name="sqlsecandparsetrees" />
    <h3>10.7.2. SQL Security and Parse Trees</h3>
  <p>
When compiling table access the access rights granted on the table are checked against
the user and group marked on the table reference (TABLE_DOTTED) parse tree node.  When
a user writes a table reference the user id and group of the user are marked in the
parse tree and these are compared against the grants in effect.
</p>
  <p>
When a table reference comes from a view the reference is annotated with the view owner&#39;s
user id and group.  Hence a view may introduce references that would not otherwise be granted to a user.
</p>
  <p>
This is used in the need to know example, marking the group and user of the reference to
NEED_TO_KNOW to be 0, meaning dba.
</p>
  <p>
There are no other security related features in the parse tree.  Procedure security is resolved
exclusively at run time.
</p>
<br />

<a name="debuggingparsetree" />
    <h3>10.7.3. Debugging with Parse Trees</h3>
  <p>
It is extremely easy to make errors when manipulating parse trees in code.
A useful technique will be to print out the tree before and after the operation.  This
can be conveniently done in the hook function with dbg_obj_print, as shown in the example.
</p>
  <p>
Once the modified tree is returned to the SQL compilation, the
system checks for it for absence of cycles, so that no two branches are the same.  There
is an assertion failure if this happens.  Otherwise the tree is not checked.  Hence a
malformed tree will in all likelihood crash the server during the compilation.
</p>
<br />
<table border="0" width="90%" id="navbarbottom">
    <tr>
        <td align="left" width="33%">
          <a href="fn_dbev_prepare.html" title="SQL Statement Preparation">Previous</a>
          <br />SQL Statement Preparation</td>
     <td align="center" width="34%">
          <a href="hooks.html">Chapter Contents</a>
     </td>
        <td align="right" width="33%">
          <a href="fn_davlogins.html" title="WebDAV Logins">Next</a>
          <br />WebDAV Logins</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>