diff options
Diffstat (limited to '')
-rw-r--r-- | www/vtab.html | 1969 |
1 files changed, 1969 insertions, 0 deletions
diff --git a/www/vtab.html b/www/vtab.html new file mode 100644 index 0000000..ecace6a --- /dev/null +++ b/www/vtab.html @@ -0,0 +1,1969 @@ +<!DOCTYPE html> +<html><head> +<meta name="viewport" content="width=device-width, initial-scale=1.0"> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<link href="sqlite.css" rel="stylesheet"> +<title>The Virtual Table Mechanism Of SQLite</title> +<!-- path= --> +</head> +<body> +<div class=nosearch> +<a href="index.html"> +<img class="logo" src="images/sqlite370_banner.gif" alt="SQLite" border="0"> +</a> +<div><!-- IE hack to prevent disappearing logo --></div> +<div class="tagline desktoponly"> +Small. Fast. Reliable.<br>Choose any three. +</div> +<div class="menu mainmenu"> +<ul> +<li><a href="index.html">Home</a> +<li class='mobileonly'><a href="javascript:void(0)" onclick='toggle_div("submenu")'>Menu</a> +<li class='wideonly'><a href='about.html'>About</a> +<li class='desktoponly'><a href="docs.html">Documentation</a> +<li class='desktoponly'><a href="download.html">Download</a> +<li class='wideonly'><a href='copyright.html'>License</a> +<li class='desktoponly'><a href="support.html">Support</a> +<li class='desktoponly'><a href="prosupport.html">Purchase</a> +<li class='search' id='search_menubutton'> +<a href="javascript:void(0)" onclick='toggle_search()'>Search</a> +</ul> +</div> +<div class="menu submenu" id="submenu"> +<ul> +<li><a href='about.html'>About</a> +<li><a href='docs.html'>Documentation</a> +<li><a href='download.html'>Download</a> +<li><a href='support.html'>Support</a> +<li><a href='prosupport.html'>Purchase</a> +</ul> +</div> +<div class="searchmenu" id="searchmenu"> +<form method="GET" action="search"> +<select name="s" id="searchtype"> +<option value="d">Search Documentation</option> +<option value="c">Search Changelog</option> +</select> +<input type="text" name="q" id="searchbox" value=""> +<input type="submit" value="Go"> +</form> +</div> +</div> +<script> +function toggle_div(nm) { +var w = document.getElementById(nm); +if( w.style.display=="block" ){ +w.style.display = "none"; +}else{ +w.style.display = "block"; +} +} +function toggle_search() { +var w = document.getElementById("searchmenu"); +if( w.style.display=="block" ){ +w.style.display = "none"; +} else { +w.style.display = "block"; +setTimeout(function(){ +document.getElementById("searchbox").focus() +}, 30); +} +} +function div_off(nm){document.getElementById(nm).style.display="none";} +window.onbeforeunload = function(e){div_off("submenu");} +/* Disable the Search feature if we are not operating from CGI, since */ +/* Search is accomplished using CGI and will not work without it. */ +if( !location.origin || !location.origin.match || !location.origin.match(/http/) ){ +document.getElementById("search_menubutton").style.display = "none"; +} +/* Used by the Hide/Show button beside syntax diagrams, to toggle the */ +function hideorshow(btn,obj){ +var x = document.getElementById(obj); +var b = document.getElementById(btn); +if( x.style.display!='none' ){ +x.style.display = 'none'; +b.innerHTML='show'; +}else{ +x.style.display = ''; +b.innerHTML='hide'; +} +return false; +} +var antiRobot = 0; +function antiRobotGo(){ +if( antiRobot!=3 ) return; +antiRobot = 7; +var j = document.getElementById("mtimelink"); +if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); +} +function antiRobotDefense(){ +document.body.onmousedown=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousedown=null; +} +document.body.onmousemove=function(){ +antiRobot |= 2; +antiRobotGo(); +document.body.onmousemove=null; +} +setTimeout(function(){ +antiRobot |= 1; +antiRobotGo(); +}, 100) +antiRobotGo(); +} +antiRobotDefense(); +</script> +<div class=fancy> +<div class=nosearch> +<div class="fancy_title"> +The Virtual Table Mechanism Of SQLite +</div> +<div class="fancy_toc"> +<a onclick="toggle_toc()"> +<span class="fancy_toc_mark" id="toc_mk">►</span> +Table Of Contents +</a> +<div id="toc_sub"><div class="fancy-toc1"><a href="#introduction">1. Introduction</a></div> +<div class="fancy-toc2"><a href="#usage">1.1. Usage</a></div> +<div class="fancy-toc3"><a href="#temporary_virtual_tables">1.1.1. Temporary virtual tables</a></div> +<div class="fancy-toc3"><a href="#eponymous_virtual_tables">1.1.2. Eponymous virtual tables</a></div> +<div class="fancy-toc3"><a href="#eponymous_only_virtual_tables">1.1.3. Eponymous-only virtual tables</a></div> +<div class="fancy-toc2"><a href="#implementation">1.2. Implementation</a></div> +<div class="fancy-toc2"><a href="#virtual_tables_and_shared_cache">1.3. Virtual Tables And Shared Cache</a></div> +<div class="fancy-toc2"><a href="#creating_new_virtual_table_implementations">1.4. Creating New Virtual Table Implementations</a></div> +<div class="fancy-toc1"><a href="#virtual_table_methods">2. Virtual Table Methods</a></div> +<div class="fancy-toc2"><a href="#the_xcreate_method">2.1. The xCreate Method</a></div> +<div class="fancy-toc3"><a href="#hidden_columns_in_virtual_tables">2.1.1. Hidden columns in virtual tables</a></div> +<div class="fancy-toc3"><a href="#table_valued_functions">2.1.2. Table-valued functions</a></div> +<div class="fancy-toc3"><a href="#_without_rowid_virtual_tables_">2.1.3. WITHOUT ROWID Virtual Tables </a></div> +<div class="fancy-toc2"><a href="#the_xconnect_method">2.2. The xConnect Method</a></div> +<div class="fancy-toc2"><a href="#the_xbestindex_method">2.3. The xBestIndex Method</a></div> +<div class="fancy-toc3"><a href="#inputs">2.3.1. Inputs</a></div> +<div class="fancy-toc4"><a href="#like_glob_regexp_and_match_functions">2.3.1.1. LIKE, GLOB, REGEXP, and MATCH functions</a></div> +<div class="fancy-toc4"><a href="#limit_and_offset">2.3.1.2. LIMIT and OFFSET</a></div> +<div class="fancy-toc4"><a href="#right_hand_side_values_of_constraints">2.3.1.3. Right-hand side values of constraints</a></div> +<div class="fancy-toc3"><a href="#outputs">2.3.2. Outputs</a></div> +<div class="fancy-toc4"><a href="#omit_constraint_checking_in_bytecode">2.3.2.1. Omit constraint checking in bytecode</a></div> +<div class="fancy-toc4"><a href="#order_by_and_orderbyconsumed">2.3.2.2. ORDER BY and orderByConsumed</a></div> +<div class="fancy-toc3"><a href="#return_value">2.3.3. Return Value</a></div> +<div class="fancy-toc3"><a href="#enforcing_required_parameters_on_table_valued_functions">2.3.4. Enforcing Required Parameters On Table-Valued Functions</a></div> +<div class="fancy-toc2"><a href="#the_xdisconnect_method">2.4. The xDisconnect Method</a></div> +<div class="fancy-toc2"><a href="#the_xdestroy_method">2.5. The xDestroy Method</a></div> +<div class="fancy-toc2"><a href="#the_xopen_method">2.6. The xOpen Method</a></div> +<div class="fancy-toc2"><a href="#the_xclose_method">2.7. The xClose Method</a></div> +<div class="fancy-toc2"><a href="#the_xeof_method">2.8. The xEof Method</a></div> +<div class="fancy-toc2"><a href="#the_xfilter_method">2.9. The xFilter Method</a></div> +<div class="fancy-toc2"><a href="#the_xnext_method">2.10. The xNext Method</a></div> +<div class="fancy-toc2"><a href="#the_xcolumn_method">2.11. The xColumn Method</a></div> +<div class="fancy-toc2"><a href="#the_xrowid_method">2.12. The xRowid Method</a></div> +<div class="fancy-toc2"><a href="#the_xupdate_method">2.13. The xUpdate Method</a></div> +<div class="fancy-toc2"><a href="#the_xfindfunction_method">2.14. The xFindFunction Method</a></div> +<div class="fancy-toc2"><a href="#the_xbegin_method">2.15. The xBegin Method</a></div> +<div class="fancy-toc2"><a href="#the_xsync_method">2.16. The xSync Method</a></div> +<div class="fancy-toc2"><a href="#the_xcommit_method">2.17. The xCommit Method</a></div> +<div class="fancy-toc2"><a href="#the_xrollback_method">2.18. The xRollback Method</a></div> +<div class="fancy-toc2"><a href="#the_xrename_method">2.19. The xRename Method</a></div> +<div class="fancy-toc2"><a href="#the_xsavepoint_xrelease_and_xrollbackto_methods">2.20. The xSavepoint, xRelease, and xRollbackTo Methods</a></div> +<div class="fancy-toc2"><a href="#the_xshadowname_method">2.21. The xShadowName Method</a></div> +</div> +</div> +<script> +function toggle_toc(){ +var sub = document.getElementById("toc_sub") +var mk = document.getElementById("toc_mk") +if( sub.style.display!="block" ){ +sub.style.display = "block"; +mk.innerHTML = "▼"; +} else { +sub.style.display = "none"; +mk.innerHTML = "►"; +} +} +</script> +</div> + + + + + + +<h1 id="introduction"><span>1. </span>Introduction</h1> + +<p>A virtual table is an object that is registered with an open SQLite +<a href="c3ref/sqlite3.html">database connection</a>. From the perspective of an SQL statement, +the virtual table object looks like any other table or view. +But behind the scenes, queries and updates on a virtual table +invoke callback methods of the virtual table object instead of +reading and writing on the database file. + +</p><p>The virtual table mechanism allows an application to publish +interfaces that are accessible from SQL statements as if they were +tables. SQL statements can do almost anything to a +virtual table that they can do to a real table, with the following +exceptions: + +</p><p> +</p><ul> +<li> One cannot create a trigger on a virtual table. +</li><li> One cannot create additional indices on a virtual table. + (Virtual tables can have indices but that must be built into + the virtual table implementation. Indices cannot be added + separately using <a href="lang_createindex.html">CREATE INDEX</a> statements.) +</li><li> One cannot run <a href="lang_altertable.html">ALTER TABLE ... ADD COLUMN</a> + commands against a virtual table. +</li></ul> + +<p>Individual virtual table implementations might impose additional +constraints. For example, some virtual implementations might provide +read-only tables. Or some virtual table implementations might allow +<a href="lang_insert.html">INSERT</a> or <a href="lang_delete.html">DELETE</a> but not <a href="lang_update.html">UPDATE</a>. Or some virtual table implementations +might limit the kinds of UPDATEs that can be made. + +</p><p>A virtual table might represent an in-memory data structures. +Or it might represent a view of data on disk that is not in the +SQLite format. Or the application might compute the content of the +virtual table on demand. + +</p><p>Here are some existing and postulated uses for virtual tables: + +</p><ul> +<li> A <a href="fts3.html">full-text search</a> interface +</li><li> Spatial indices using <a href="rtree.html">R-Trees</a> +</li><li> Introspect the disk content of an SQLite database file + (the <a href="dbstat.html">dbstat virtual table</a>) +</li><li> Read and/or write the content of a comma-separated value (CSV) + file +</li><li> Access the filesystem of the host computer as if it were a database table +</li><li> Enabling SQL manipulation of data in statistics packages like R +</li></ul> + +<p>See the <a href="vtablist.html">list of virtual tables</a> page for a longer list of actual +virtual table implementations. + + +</p><h2 id="usage"><span>1.1. </span>Usage</h2> + +<p>A virtual table is created using a <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. + +<p><b><a href="syntax/create-virtual-table-stmt.html">create-virtual-table-stmt:</a></b> +<button id='x2353' onclick='hideorshow("x2353","x2354")'>hide</button></p> + <div id='x2354' class='imgcontainer'> + <div style="max-width:624px"><svg xmlns='http://www.w3.org/2000/svg' class="pikchr" viewBox="0 0 624.096 259.848"> +<circle cx="5" cy="17" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="32,17 20,21 20,12" style="fill:rgb(0,0,0)"/> +<path d="M9,17L26,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M47,32L100,32A15 15 0 0 0 116 17A15 15 0 0 0 100 2L47,2A15 15 0 0 0 32 17A15 15 0 0 0 47 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="74" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">CREATE</text> +<polygon points="139,17 127,21 127,12" style="fill:rgb(0,0,0)"/> +<path d="M116,17L133,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M154,32L213,32A15 15 0 0 0 228 17A15 15 0 0 0 213 2L154,2A15 15 0 0 0 139 17A15 15 0 0 0 154 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="183" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">VIRTUAL</text> +<polygon points="251,17 240,21 240,12" style="fill:rgb(0,0,0)"/> +<path d="M228,17L246,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M266,32L306,32A15 15 0 0 0 321 17A15 15 0 0 0 306 2L266,2A15 15 0 0 0 251 17A15 15 0 0 0 266 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="286" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">TABLE</text> +<polygon points="357,17 345,21 345,12" style="fill:rgb(0,0,0)"/> +<path d="M321,17L351,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M372,32A15 15 0 0 0 387 17A15 15 0 0 0 372 2A15 15 0 0 0 357 17A15 15 0 0 0 372 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="372" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">IF</text> +<polygon points="410,17 399,21 399,12" style="fill:rgb(0,0,0)"/> +<path d="M387,17L404,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M425,32L445,32A15 15 0 0 0 461 17A15 15 0 0 0 445 2L425,2A15 15 0 0 0 410 17A15 15 0 0 0 425 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="435" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">NOT</text> +<polygon points="484,17 472,21 472,12" style="fill:rgb(0,0,0)"/> +<path d="M461,17L478,17" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M499,32L543,32A15 15 0 0 0 558 17A15 15 0 0 0 543 2L499,2A15 15 0 0 0 484 17A15 15 0 0 0 499 32Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="521" y="17" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">EXISTS</text> +<path d="M47,108L143,108A15 15 0 0 0 159 92A15 15 0 0 0 143 77L47,77A15 15 0 0 0 32 92A15 15 0 0 0 47 108Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="95" y="92" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">schema-name</text> +<polygon points="182,92 170,97 170,88" style="fill:rgb(0,0,0)"/> +<path d="M159,92L176,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M197,108A15 15 0 0 0 212 92A15 15 0 0 0 197 77A15 15 0 0 0 182 92A15 15 0 0 0 197 108Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="197" y="92" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">.</text> +<polygon points="248,92 236,97 236,88" style="fill:rgb(0,0,0)"/> +<path d="M212,92L242,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M263,108L338,108A15 15 0 0 0 353 92A15 15 0 0 0 338 77L263,77A15 15 0 0 0 248 92A15 15 0 0 0 263 108Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="300" y="92" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">table-name</text> +<path d="M47,219L86,219A15 15 0 0 0 101 204A15 15 0 0 0 86 189L47,189A15 15 0 0 0 32 204A15 15 0 0 0 47 219Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="67" y="204" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">USING</text> +<polygon points="124,204 113,209 113,200" style="fill:rgb(0,0,0)"/> +<path d="M101,204L118,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M139,219L234,219A15 15 0 0 0 249 204A15 15 0 0 0 234 189L139,189A15 15 0 0 0 124 204A15 15 0 0 0 139 219Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="187" y="204" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">module-name</text> +<polygon points="285,204 274,209 274,200" style="fill:rgb(0,0,0)"/> +<path d="M249,204L279,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M300,219A15 15 0 0 0 315 204A15 15 0 0 0 300 189A15 15 0 0 0 285 204A15 15 0 0 0 300 219Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="300" y="204" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">(</text> +<polygon points="351,204 340,209 340,200" style="fill:rgb(0,0,0)"/> +<path d="M315,204L346,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M366,219L497,219A15 15 0 0 0 512 204A15 15 0 0 0 497 189L366,189A15 15 0 0 0 351 204A15 15 0 0 0 366 219Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="432" y="204" text-anchor="middle" fill="rgb(0,0,0)" dominant-baseline="central">module-argument</text> +<polygon points="548,204 536,209 536,200" style="fill:rgb(0,0,0)"/> +<path d="M512,204L542,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M563,219A15 15 0 0 0 578 204A15 15 0 0 0 563 189A15 15 0 0 0 548 204A15 15 0 0 0 563 219Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="563" y="204" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">)</text> +<polygon points="614,204 603,209 603,200" style="fill:rgb(0,0,0)"/> +<path d="M578,204L608,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<circle cx="618" cy="204" r="3.6" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M432,257A15 15 0 0 0 447 242A15 15 0 0 0 432 227A15 15 0 0 0 417 242A15 15 0 0 0 432 257Z" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<text x="432" y="242" text-anchor="middle" font-weight="bold" fill="rgb(0,0,0)" dominant-baseline="central">,</text> +<polygon points="447,242 458,238 458,246" style="fill:rgb(0,0,0)"/> +<path d="M512,204 L 519,204 Q 527,204 527,219 L 527,227 Q 527,242 512,242 L 468,242 L 453,242" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M417,242 L 343,242 Q 328,242 328,227 L 328,219 Q 328,204 336,204 L 343,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="432,180 420,184 420,176" style="fill:rgb(0,0,0)"/> +<path d="M249,204 L 257,204 Q 264,204 264,192 Q 264,180 279,180 L 411,180 L 426,180" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M432,180 L 576,180 Q 591,180 591,192 Q 591,204 599,204 L 606,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="187,153 198,149 198,157" style="fill:rgb(0,0,0)"/> +<path d="M353,92 L 361,92 Q 368,92 368,107 L 368,138 Q 368,153 353,153 L 207,153 L 192,153" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="32,204 20,209 20,200" style="fill:rgb(0,0,0)"/> +<path d="M187,153 L 20,153 Q 5,153 5,168 L 5,189 Q 5,204 16,204 L 26,204" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="429,62 441,58 441,66" style="fill:rgb(0,0,0)"/> +<path d="M558,17 L 566,17 Q 573,17 573,32 L 573,47 Q 573,62 558,62 L 450,62 L 435,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="32,92 20,97 20,88" style="fill:rgb(0,0,0)"/> +<path d="M429,62 L 20,62 Q 5,62 5,77 L 5,77 Q 5,92 16,92 L 26,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="336,47 332,35 340,35" style="fill:rgb(0,0,0)"/> +<path d="M321,17 L 328,17 Q 336,17 336,29 L 336,41" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M336,47 L 336,54 Q 336,62 328,62 L 321,62" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<polygon points="95,123 84,127 84,118" style="fill:rgb(0,0,0)"/> +<path d="M5,77 L 5,108 Q 5,123 20,123 L 74,123 L 89,123" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +<path d="M95,123 L 210,123 Q 225,123 225,108 L 225,107 Q 225,92 231,92 L 236,92" style="fill:none;stroke-width:2.16;stroke:rgb(0,0,0);" /> +</svg> +</div> +</div> + + +</p><p>The CREATE VIRTUAL TABLE statement creates a new table +called <span class='yyterm'>table-name</span> derived from the class +<span class='yyterm'>module-name</span>. The <span class='yyterm'>module-name</span> +is the name that is registered for the virtual table by +the <a href="c3ref/create_module.html">sqlite3_create_module()</a> interface. + +</p><div class="codeblock"><pre>CREATE VIRTUAL TABLE tablename USING modulename; +</pre></div> + +<p>One can also provide comma-separated arguments to the module following +the module name: + +</p><div class="codeblock"><pre>CREATE VIRTUAL TABLE tablename USING modulename(arg1, arg2, ...); +</pre></div> + +<p>The format of the arguments to the module is very general. Each +<span class='yyterm'>module-argument</span> +may contain keywords, string literals, identifiers, numbers, and +punctuation. Each <span class='yyterm'>module-argument</span> is passed as +written (as text) into the +<a href="vtab.html#xcreate">constructor method</a> of the virtual table implementation +when the virtual +table is created and that constructor is responsible for parsing and +interpreting the arguments. The argument syntax is sufficiently general +that a virtual table implementation can, if it wants to, interpret its +arguments as <a href="lang_createtable.html#tablecoldef">column definitions</a> in an ordinary <a href="lang_createtable.html">CREATE TABLE</a> statement. +The implementation could also impose some other interpretation on the +arguments. + +</p><p>Once a virtual table has been created, it can be used like any other +table with the exceptions noted above and imposed by specific virtual +table implementations. A virtual table is destroyed using the ordinary +<a href="lang_droptable.html">DROP TABLE</a> syntax. + +</p><h3 id="temporary_virtual_tables"><span>1.1.1. </span>Temporary virtual tables</h3> + +<p>There is no "CREATE TEMP VIRTUAL TABLE" statement. To create a +temporary virtual table, add the "temp" schema +before the virtual table name. + +</p><div class="codeblock"><pre>CREATE VIRTUAL TABLE <b>temp.</b>tablename USING module(arg1, ...); +</pre></div> + +<a name="epovtab"></a> + +<h3 id="eponymous_virtual_tables"><span>1.1.2. </span>Eponymous virtual tables</h3> + +<p>Some virtual tables exist automatically in the "main" schema of +every database connection in which their +module is registered, even without a <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. +Such virtual tables are called "eponymous virtual tables". +To use an eponymous virtual table, simply use the +module name as if it were a table. +Eponymous virtual tables exist in the "main" schema only, so they will +not work if prefixed with a different schema name. + +</p><p>An example of an eponymous virtual table is the <a href="dbstat.html">dbstat virtual table</a>. +To use the dbstat virtual table as an eponymous virtual table, +simply query against the "dbstat" +module name, as if it were an ordinary table. (Note that SQLite +must be compiled with the <a href="compile.html#enable_dbstat_vtab">SQLITE_ENABLE_DBSTAT_VTAB</a> option to include +the dbstat virtual table in the build.) + +</p><div class="codeblock"><pre>SELECT * FROM dbstat; +</pre></div> + +<p>A virtual table is eponymous if its <a href="vtab.html#xcreate">xCreate</a> method is the exact same +function as the <a href="vtab.html#xconnect">xConnect</a> method, or if the <a href="vtab.html#xcreate">xCreate</a> method is NULL. +The <a href="vtab.html#xcreate">xCreate</a> method is called when a virtual table is first created +using the <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. The <a href="vtab.html#xconnect">xConnect</a> method +is invoked whenever +a database connection attaches to or reparses a schema. When these two methods +are the same, that indicates that the virtual table has no persistent +state that needs to be created and destroyed. + +<a name="epoonlyvtab"></a> + +</p><h3 id="eponymous_only_virtual_tables"><span>1.1.3. </span>Eponymous-only virtual tables</h3> +<p>If the <a href="vtab.html#xcreate">xCreate</a> method is NULL, then +<a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statements are prohibited for that virtual table, +and the virtual table is an "eponymous-only virtual table". +Eponymous-only virtual tables are useful as +<a href="vtab.html#tabfunc2">table-valued functions</a>. + +</p><p> +Note that prior to <a href="releaselog/3_9_0.html">version 3.9.0</a> (2015-10-14), +SQLite did not check the xCreate method +for NULL before invoking it. So if an eponymous-only virtual table is +registered with SQLite <a href="releaselog/3_8_11_1.html">version 3.8.11.1</a> (2015-07-29) +or earlier and a <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> +command is attempted against that virtual table module, a jump to a NULL +pointer will occur, resulting in a crash. + +</p><h2 id="implementation"><span>1.2. </span>Implementation</h2> + +<p>Several new C-level objects are used by the virtual table implementation: + +</p><div class="codeblock"><pre>typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; +</pre></div> + +<p>The <a href="c3ref/module.html">sqlite3_module</a> structure defines a module object used to implement +a virtual table. Think of a module as a class from which one can +construct multiple virtual tables having similar properties. For example, +one might have a module that provides read-only access to +comma-separated-value (CSV) files on disk. That one module can then be +used to create several virtual tables where each virtual table refers +to a different CSV file. + +</p><p>The module structure contains methods that are invoked by SQLite to +perform various actions on the virtual table such as creating new +instances of a virtual table or destroying old ones, reading and +writing data, searching for and deleting, updating, or inserting rows. +The module structure is explained in more detail below. + +</p><p>Each virtual table instance is represented by an <a href="c3ref/vtab.html">sqlite3_vtab</a> structure. +The sqlite3_vtab structure looks like this: + +</p><div class="codeblock"><pre>struct sqlite3_vtab { + const sqlite3_module *pModule; + int nRef; + char *zErrMsg; +}; +</pre></div> + +<p>Virtual table implementations will normally subclass this structure +to add additional private and implementation-specific fields. +The nRef field is used internally by the SQLite core and should not +be altered by the virtual table implementation. The virtual table +implementation may pass error message text to the core by putting +an error message string in zErrMsg. +Space to hold this error message string must be obtained from an +SQLite memory allocation function such as <a href="c3ref/mprintf.html">sqlite3_mprintf()</a> or +<a href="c3ref/free.html">sqlite3_malloc()</a>. +Prior to assigning a new value to zErrMsg, the virtual table +implementation must free any preexisting content of zErrMsg using +<a href="c3ref/free.html">sqlite3_free()</a>. Failure to do this will result in a memory leak. +The SQLite core will free and zero the content of zErrMsg when it +delivers the error message text to the client application or when +it destroys the virtual table. The virtual table implementation only +needs to worry about freeing the zErrMsg content when it overwrites +the content with a new, different error message. + +</p><p>The <a href="c3ref/vtab_cursor.html">sqlite3_vtab_cursor</a> structure represents a pointer to a specific +row of a virtual table. This is what an sqlite3_vtab_cursor looks like: + +</p><div class="codeblock"><pre>struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; +}; +</pre></div> + +<p>Once again, practical implementations will likely subclass this +structure to add additional private fields. + +</p><p>The <a href="c3ref/index_info.html">sqlite3_index_info</a> structure is used to pass information into +and out of the xBestIndex method of the module that implements a +virtual table. + +</p><p>Before a <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement can be run, the module +specified in that statement must be registered with the database +connection. This is accomplished using either of the <a href="c3ref/create_module.html">sqlite3_create_module()</a> +or <a href="c3ref/create_module.html">sqlite3_create_module_v2()</a> interfaces: + +</p><div class="codeblock"><pre>int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ +); +int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ + const char *zName, /* Name of the module */ + const sqlite3_module *, /* Methods for the module */ + void *, /* Client data for xCreate/xConnect */ + void(*xDestroy)(void*) /* Client data destructor function */ +); +</pre></div> + +<p>The <a href="c3ref/create_module.html">sqlite3_create_module()</a> and <a href="c3ref/create_module.html">sqlite3_create_module_v2()</a> +routines associates a module name with +an <a href="c3ref/module.html">sqlite3_module</a> structure and a separate client data that is specific +to each module. The only difference between the two create_module methods +is that the _v2 method includes an extra parameter that specifies a +destructor for client data pointer. The module structure is what defines +the behavior of a virtual table. The module structure looks like this: + +</p><div class="codeblock"><pre> +struct sqlite3_module { + int iVersion; + int (*xCreate)(sqlite3*, void *pAux, + int argc, char *const*argv, + sqlite3_vtab **ppVTab, + char **pzErr); + int (*xConnect)(sqlite3*, void *pAux, + int argc, char *const*argv, + sqlite3_vtab **ppVTab, + char **pzErr); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + /* The methods above are in version 1 of the sqlite_module object. Those + ** below are for version 2 and greater. */ + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); + /* The methods above are in versions 1 and 2 of the sqlite_module object. + ** Those below are for version 3 and greater. */ + int (*xShadowName)(const char*); +}; +</pre></div> + +<p>The module structure defines all of the methods for each virtual +table object. The module structure also contains the iVersion field which +defines the particular edition of the module table structure. Currently, +iVersion is always 3 or less, but in future releases of SQLite the module +structure definition might be extended with additional methods and in +that case the maximum iVersion value will be increased. + +</p><p>The rest of the module structure consists of methods used to implement +various features of the virtual table. Details on what each of these +methods do are provided in the sequel. + +</p><h2 id="virtual_tables_and_shared_cache"><span>1.3. </span>Virtual Tables And Shared Cache</h2> + +<p>Prior to SQLite <a href="releaselog/3_6_17.html">version 3.6.17</a> (2009-08-10), +the virtual table mechanism assumes +that each <a href="c3ref/sqlite3.html">database connection</a> kept +its own copy of the database schema. Hence, the virtual table mechanism +could not be used in a database that has <a href="sharedcache.html">shared cache mode</a> enabled. +The <a href="c3ref/create_module.html">sqlite3_create_module()</a> interface would return an error if +<a href="sharedcache.html">shared cache mode</a> is enabled. That restriction was relaxed +beginning with SQLite <a href="releaselog/3_6_17.html">version 3.6.17</a>. + +<a name="customvtab"></a> + +</p><h2 id="creating_new_virtual_table_implementations"><span>1.4. </span>Creating New Virtual Table Implementations</h2> + +<p>Follow these steps to create your own virtual table: + +</p><p> +</p><ol> +<li> Write all necessary methods. +</li><li> Create an instance of the <a href="c3ref/module.html">sqlite3_module</a> structure containing pointers + to all the methods from step 1. +</li><li> Register your <a href="c3ref/module.html">sqlite3_module</a> structure using one of the + <a href="c3ref/create_module.html">sqlite3_create_module()</a> or <a href="c3ref/create_module.html">sqlite3_create_module_v2()</a> interfaces. +</li><li> Run a <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> command that specifies the new module in + the USING clause. +</li></ol> + +<p>The only really hard part is step 1. You might want to start with an +existing virtual table implementation and modify it to suit your needs. +The <a href="https://sqlite.org/src/dir?ci=trunk&type=tree">SQLite source tree</a> +contains many virtual table implementations that are suitable for copying, +including: + +</p><p> +</p><ul> +<li> <b><a href="https://sqlite.org/src/file/ext/misc/templatevtab.c">templatevtab.c</a></b> +→ A virtual table created specifically to serve as a template for +other custom virtual tables. +</li><li> <b><a href="https://sqlite.org/src/file/ext/misc/series.c">series.c</a></b> +→ Implementation of the generate_series() table-valued function. +</li><li> <b><a href="https://sqlite.org/src/file/src/json.c">json.c</a></b> → +Contains the sources for the <a href="json1.html#jeach">json_each()</a> and <a href="json1.html#jtree">json_tree()</a> table-valued +functions. +</li><li> <b><a href="https://sqlite.org/src/file/ext/misc/csv.c">csv.c</a></b> → +A virtual table that reads CSV files. +</li></ul> + + +<p>There are <a href="vtablist.html">many other virtual table implementations</a> +in the SQLite source tree that can be used as examples. Locate +these other virtual table implementations by searching +for "sqlite3_create_module". + +</p><p>You might also want to implement your new virtual table as a +<a href="loadext.html">loadable extension</a>. + +</p><h1 id="virtual_table_methods"><span>2. </span>Virtual Table Methods</h1> + +<a name="xcreate"></a> + +<h2 id="the_xcreate_method"><span>2.1. </span>The xCreate Method</h2> + +<div class="codeblock"><pre>int (*xCreate)(sqlite3 *db, void *pAux, + int argc, char *const*argv, + sqlite3_vtab **ppVTab, + char **pzErr); +</pre></div> + +<p>The xCreate method is called to create a new instance of a virtual table +in response to a <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. +If the xCreate method is the same pointer as the <a href="vtab.html#xconnect">xConnect</a> method, then the +virtual table is an <a href="vtab.html#epovtab">eponymous virtual table</a>. +If the xCreate method is omitted (if it is a NULL pointer) then the virtual +table is an <a href="vtab.html#epoonlyvtab">eponymous-only virtual table</a>. + + +</p><p>The db parameter is a pointer to the SQLite <a href="c3ref/sqlite3.html">database connection</a> that +is executing the <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. +The pAux argument is the copy of the client data pointer that was the +fourth argument to the <a href="c3ref/create_module.html">sqlite3_create_module()</a> or +<a href="c3ref/create_module.html">sqlite3_create_module_v2()</a> call that registered the +<a href="c3ref/module.html">virtual table module</a>. +The argv parameter is an array of argc pointers to null terminated strings. +The first string, argv[0], is the name of the module being invoked. The +module name is the name provided as the second argument to +<a href="c3ref/create_module.html">sqlite3_create_module()</a> and as the argument to the USING clause of the +<a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement that is running. +The second, argv[1], is the name of the database in which the new virtual +table is being created. The database name is "main" for the primary database, or +"temp" for TEMP database, or the name given at the end of the <a href="lang_attach.html">ATTACH</a> +statement for attached databases. The third element of the array, argv[2], +is the name of the new virtual table, as specified following the TABLE +keyword in the <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. +If present, the fourth and subsequent strings in the argv[] array report +the arguments to the module name in the <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> statement. + +</p><p>The job of this method is to construct the new virtual table object +(an <a href="c3ref/vtab.html">sqlite3_vtab</a> object) and return a pointer to it in *ppVTab. + +</p><p>As part of the task of creating a new <a href="c3ref/vtab.html">sqlite3_vtab</a> structure, this +method <u>must</u> invoke <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> to tell the SQLite +core about the columns and datatypes in the virtual table. +The <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> API has the following prototype: + +</p><div class="codeblock"><pre>int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable) +</pre></div> + +<p>The first argument to <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> must be the same +<a href="c3ref/sqlite3.html">database connection</a> pointer as the first parameter to this method. +The second argument to <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> must a zero-terminated +UTF-8 string that contains a well-formed <a href="lang_createtable.html">CREATE TABLE</a> statement that +defines the columns in the virtual table and their data types. +The name of the table in this CREATE TABLE statement is ignored, +as are all constraints. Only the column names and datatypes matter. +The CREATE TABLE statement string need not to be +held in persistent memory. The string can be +deallocated and/or reused as soon as the <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> +routine returns. + +</p><p>The xConnect method can also optionally request special features +for the virtual table by making one or more calls to +the <a href="c3ref/vtab_config.html">sqlite3_vtab_config()</a> interface: + +</p><div class="codeblock"><pre>int sqlite3_vtab_config(sqlite3 *db, int op, ...); +</pre></div> + +<p>Calls to sqlite3_vtab_config() are optional. But for maximum +security, it is recommended that virtual table implementations +invoke "<a href="c3ref/vtab_config.html">sqlite3_vtab_config</a>(db, <a href="c3ref/c_vtab_constraint_support.html#sqlitevtabdirectonly">SQLITE_VTAB_DIRECTONLY</a>)" if the +virtual table will not be used from inside of triggers or views. + +</p><p>The xCreate method need not initialize the pModule, nRef, and zErrMsg +fields of the <a href="c3ref/vtab.html">sqlite3_vtab</a> object. The SQLite core will take care of +that chore. + +</p><p>The xCreate should return <a href="rescode.html#ok">SQLITE_OK</a> if it is successful in +creating the new virtual table, or <a href="rescode.html#error">SQLITE_ERROR</a> if it is not successful. +If not successful, the <a href="c3ref/vtab.html">sqlite3_vtab</a> structure must not be allocated. +An error message may optionally be returned in *pzErr if unsuccessful. +Space to hold the error message string must be allocated using +an SQLite memory allocation function like +<a href="c3ref/free.html">sqlite3_malloc()</a> or <a href="c3ref/mprintf.html">sqlite3_mprintf()</a> as the SQLite core will +attempt to free the space using <a href="c3ref/free.html">sqlite3_free()</a> after the error has +been reported up to the application. + +</p><p> +If the xCreate method is omitted (left as a NULL pointer) then the +virtual table is an <a href="vtab.html#epoonlyvtab">eponymous-only virtual table</a>. New instances of +the virtual table cannot be created using <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> and the +virtual table can only be used via its module name. +Note that SQLite versions prior to 3.9.0 (2015-10-14) do not understand +eponymous-only virtual tables and will segfault if an attempt is made +to <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> on an eponymous-only virtual table because +the xCreate method was not checked for null. + +</p><p> +If the xCreate method is the exact same pointer as the <a href="vtab.html#xconnect">xConnect</a> method, +that indicates that the virtual table does not need to initialize backing +store. Such a virtual table can be used as an <a href="vtab.html#epovtab">eponymous virtual table</a> +or as a named virtual table using <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a> or both. + +<a name="hiddencol"></a> + +</p><h3 id="hidden_columns_in_virtual_tables"><span>2.1.1. </span>Hidden columns in virtual tables</h3> +<p>If a column datatype contains the special keyword "HIDDEN" +(in any combination of upper and lower case letters) then that keyword +it is omitted from the column datatype name and the column is marked +as a hidden column internally. +A hidden column differs from a normal column in three respects: + +</p><p> +</p><ul> +<li> Hidden columns are not listed in the dataset returned by + "<a href="pragma.html#pragma_table_info">PRAGMA table_info</a>", +</li><li> Hidden columns are not included in the expansion of a "*" + expression in the result set of a <a href="lang_select.html">SELECT</a>, and +</li><li> Hidden columns are not included in the implicit column-list + used by an <a href="lang_insert.html">INSERT</a> statement that lacks an explicit column-list. +</li></ul> + +<p>For example, if the following SQL is passed to <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a>: + +</p><div class="codeblock"><pre>CREATE TABLE x(a HIDDEN VARCHAR(12), b INTEGER, c INTEGER Hidden); +</pre></div> + +<p>Then the virtual table would be created with two hidden columns, +and with datatypes of "VARCHAR(12)" and "INTEGER". + +</p><p>An example use of hidden columns can be seen in the <a href="fts3.html">FTS3</a> virtual +table implementation, where every FTS virtual table +contains an <a href="fts3.html#hiddencol">FTS hidden column</a> that is used to pass information from the +virtual table into <a href="fts3.html#snippet">FTS auxiliary functions</a> and to the <a href="fts3.html#full_text_index_queries">FTS MATCH</a> operator. + +<a name="tabfunc2"></a> + +</p><h3 id="table_valued_functions"><span>2.1.2. </span>Table-valued functions</h3> + +<p>A <a href="vtab.html">virtual table</a> that contains <a href="vtab.html#hiddencol">hidden columns</a> can be used like +a table-valued function in the FROM clause of a <a href="lang_select.html">SELECT</a> statement. +The arguments to the table-valued function become constraints on +the HIDDEN columns of the virtual table. + +</p><p>For example, the "generate_series" extension (located in the +<a href="http://www.sqlite.org/src/artifact?ci=trunk&filename=ext/misc/series.c">ext/misc/series.c</a> +file in the <a href="http://www.sqlite.org/src/tree?ci=trunk">source tree</a>) +implements an <a href="vtab.html#epovtab">eponymous virtual table</a> with the following schema: + +</p><div class="codeblock"><pre>CREATE TABLE generate_series( + value, + start HIDDEN, + stop HIDDEN, + step HIDDEN +); +</pre></div> + +<p>The <a href="vtab.html#xbestindex">sqlite3_module.xBestIndex</a> method in the implementation of this +table checks for equality constraints against the HIDDEN columns, and uses +those as input parameters to determine the range of integer "value" outputs +to generate. Reasonable defaults are used for any unconstrained columns. +For example, to list all integers between 5 and 50: + +</p><div class="codeblock"><pre>SELECT value FROM generate_series(5,50); +</pre></div> + +<p>The previous query is equivalent to the following: + +</p><div class="codeblock"><pre>SELECT value FROM generate_series WHERE start=5 AND stop=50; +</pre></div> + +<p>Arguments on the virtual table name are matched to <a href="vtab.html#hiddencol">hidden columns</a> +in order. The number of arguments can be less than the +number of hidden columns, in which case the latter hidden columns are +unconstrained. However, an error results if there are more arguments +than there are hidden columns in the virtual table. + +<a name="worid"></a> + +</p><h3 id="_without_rowid_virtual_tables_"><span>2.1.3. </span> WITHOUT ROWID Virtual Tables </h3> + +<p>Beginning with SQLite <a href="releaselog/3_14.html">version 3.14.0</a> (2016-08-08), +the CREATE TABLE statement that +is passed into <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> may contain a <a href="withoutrowid.html">WITHOUT ROWID</a> clause. +This is useful for cases where the virtual table rows +cannot easily be mapped into unique integers. A CREATE TABLE +statement that includes WITHOUT ROWID must define one or more columns as +the PRIMARY KEY. Every column of the PRIMARY KEY must individually be +NOT NULL and all columns for each row must be collectively unique. + +</p><p>Note that SQLite does not enforce the PRIMARY KEY for a WITHOUT ROWID +virtual table. Enforcement is the responsibility of the underlying +virtual table implementation. But SQLite does assume that the PRIMARY KEY +constraint is valid - that the identified columns really are UNIQUE and +NOT NULL - and it uses that assumption to optimize queries against the +virtual table. + +</p><p>The rowid column is not accessible on a +WITHOUT ROWID virtual table (of course). + +</p><p>The <a href="vtab.html#xupdate">xUpdate</a> method was originally designed around having a +<a href="lang_createtable.html#rowid">ROWID</a> as a single value. The <a href="vtab.html#xupdate">xUpdate</a> method has been expanded to +accommodate an arbitrary PRIMARY KEY in place of the ROWID, but the +PRIMARY KEY must still be only one column. For this reason, SQLite +will reject any WITHOUT ROWID virtual table that has more than one +PRIMARY KEY column and a non-NULL xUpdate method. + +<a name="xconnect"></a> + +</p><h2 id="the_xconnect_method"><span>2.2. </span>The xConnect Method</h2> + +<div class="codeblock"><pre>int (*xConnect)(sqlite3*, void *pAux, + int argc, char *const*argv, + sqlite3_vtab **ppVTab, + char **pzErr); +</pre></div> + +<p>The xConnect method is very similar to <a href="vtab.html#xcreate">xCreate</a>. +It has the same parameters and constructs a new <a href="c3ref/vtab.html">sqlite3_vtab</a> structure +just like xCreate. +And it must also call <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> like xCreate. It +should also make all of the same <a href="c3ref/vtab_config.html">sqlite3_vtab_config()</a> calls as +xCreate. + +</p><p>The difference is that xConnect is called to establish a new +connection to an existing virtual table whereas xCreate is called +to create a new virtual table from scratch. + +</p><p>The xCreate and xConnect methods are only different when the +virtual table has some kind of backing store that must be initialized +the first time the virtual table is created. The xCreate method creates +and initializes the backing store. The xConnect method just connects +to an existing backing store. When xCreate and xConnect are the same, +the table is an <a href="vtab.html#epovtab">eponymous virtual table</a>. + +</p><p>As an example, consider a virtual table implementation that +provides read-only access to existing comma-separated-value (CSV) +files on disk. There is no backing store that needs to be created +or initialized for such a virtual table (since the CSV files already +exist on disk) so the xCreate and xConnect methods will be identical +for that module. + +</p><p>Another example is a virtual table that implements a full-text index. +The xCreate method must create and initialize data structures to hold +the dictionary and posting lists for that index. The xConnect method, +on the other hand, only has to locate and use an existing dictionary +and posting lists that were created by a prior xCreate call. + +</p><p>The xConnect method must return <a href="rescode.html#ok">SQLITE_OK</a> if it is successful +in creating the new virtual table, or <a href="rescode.html#error">SQLITE_ERROR</a> if it is not +successful. If not successful, the <a href="c3ref/vtab.html">sqlite3_vtab</a> structure must not be +allocated. An error message may optionally be returned in *pzErr if +unsuccessful. +Space to hold the error message string must be allocated using +an SQLite memory allocation function like +<a href="c3ref/free.html">sqlite3_malloc()</a> or <a href="c3ref/mprintf.html">sqlite3_mprintf()</a> as the SQLite core will +attempt to free the space using <a href="c3ref/free.html">sqlite3_free()</a> after the error has +been reported up to the application. + +</p><p>The xConnect method is required for every virtual table implementation, +though the <a href="vtab.html#xcreate">xCreate</a> and xConnect pointers of the <a href="c3ref/module.html">sqlite3_module</a> object +may point to the same function if the virtual table does not need to +initialize backing store. + +<a name="xbestindex"></a> + +</p><h2 id="the_xbestindex_method"><span>2.3. </span>The xBestIndex Method</h2> + +<p>SQLite uses the xBestIndex method of a virtual table module to determine +the best way to access the virtual table. +The xBestIndex method has a prototype like this: + +</p><div class="codeblock"><pre>int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); +</pre></div> + +<p>The SQLite core communicates with the xBestIndex method by filling +in certain fields of the <a href="c3ref/index_info.html">sqlite3_index_info</a> structure and passing a +pointer to that structure into xBestIndex as the second parameter. +The xBestIndex method fills out other fields of this structure which +forms the reply. The <a href="c3ref/index_info.html">sqlite3_index_info</a> structure looks like this: + +</p><div class="codeblock"><pre>struct sqlite3_index_info { + /* Inputs */ + const int nConstraint; /* Number of entries in aConstraint */ + const struct sqlite3_index_constraint { + int iColumn; /* Column constrained. -1 for ROWID */ + unsigned char op; /* Constraint operator */ + unsigned char usable; /* True if this constraint is usable */ + int iTermOffset; /* Used internally - xBestIndex should ignore */ + } *const aConstraint; /* Table of WHERE clause constraints */ + const int nOrderBy; /* Number of terms in the ORDER BY clause */ + const struct sqlite3_index_orderby { + int iColumn; /* Column number */ + unsigned char desc; /* True for DESC. False for ASC. */ + } *const aOrderBy; /* The ORDER BY clause */ + + /* Outputs */ + struct sqlite3_index_constraint_usage { + int argvIndex; /* if >0, constraint is part of argv to xFilter */ + unsigned char omit; /* Do not code a test for this constraint */ + } *const aConstraintUsage; + int idxNum; /* Number used to identify the index */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ + int orderByConsumed; /* True if output is already ordered */ + double estimatedCost; /* Estimated cost of using this index */ + <b>/* Fields below are only available in SQLite 3.8.2 and later */</b> + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ + <b>/* Fields below are only available in SQLite 3.9.0 and later */</b> + int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ + <b>/* Fields below are only available in SQLite 3.10.0 and later */</b> + sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ +}; +</pre></div> + +<p>Note the warnings on the "estimatedRows", "idxFlags", and colUsed fields. +These fields were added with SQLite versions 3.8.2, 3.9.0, and 3.10.0, respectively. +Any extension that reads or writes these fields must first check that the +version of the SQLite library in use is greater than or equal to appropriate +version - perhaps comparing the value returned from <a href="c3ref/libversion.html">sqlite3_libversion_number()</a> +against constants 3008002, 3009000, and/or 3010000. The result of attempting +to access these fields in an sqlite3_index_info structure created by an +older version of SQLite are undefined. + +</p><p>In addition, there are some defined constants: + +</p><div class="codeblock"><pre>#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 /* 3.10.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 /* 3.10.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 /* 3.10.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_NE 68 /* 3.21.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 /* 3.21.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 /* 3.21.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 /* 3.21.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_IS 72 /* 3.21.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 /* 3.38.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 /* 3.38.0 and later */ +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* 3.25.0 and later */ +#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ +</pre></div> + +<p>Use the <a href="c3ref/vtab_collation.html">sqlite3_vtab_collation()</a> interface to find the name of +the <a href="datatype3.html#collation">collating sequence</a> that should be used when evaluating the i-th +constraint: + +</p><div class="codeblock"><pre>const char *sqlite3_vtab_collation(sqlite3_index_info*, int i); +</pre></div> + +<p>The SQLite core calls the xBestIndex method when it is compiling a query +that involves a virtual table. In other words, SQLite calls this method +when it is running <a href="c3ref/prepare.html">sqlite3_prepare()</a> or the equivalent. +By calling this method, the +SQLite core is saying to the virtual table that it needs to access +some subset of the rows in the virtual table and it wants to know the +most efficient way to do that access. The xBestIndex method replies +with information that the SQLite core can then use to conduct an +efficient search of the virtual table. + +</p><p>While compiling a single SQL query, the SQLite core might call +xBestIndex multiple times with different settings in <a href="c3ref/index_info.html">sqlite3_index_info</a>. +The SQLite core will then select the combination that appears to +give the best performance. + +</p><p>Before calling this method, the SQLite core initializes an instance +of the <a href="c3ref/index_info.html">sqlite3_index_info</a> structure with information about the +query that it is currently trying to process. This information +derives mainly from the WHERE clause and ORDER BY or GROUP BY clauses +of the query, but also from any ON or USING clauses if the query is a +join. The information that the SQLite core provides to the xBestIndex +method is held in the part of the structure that is marked as "Inputs". +The "Outputs" section is initialized to zero. + +</p><p>The information in the <a href="c3ref/index_info.html">sqlite3_index_info</a> structure is ephemeral +and may be overwritten or deallocated as soon as the xBestIndex method +returns. If the xBestIndex method needs to remember any part of the +<a href="c3ref/index_info.html">sqlite3_index_info</a> structure, it should make a copy. Care must be +take to store the copy in a place where it will be deallocated, such +as in the idxStr field with needToFreeIdxStr set to 1. + +</p><p>Note that xBestIndex will always be called before <a href="vtab.html#xfilter">xFilter</a>, since +the idxNum and idxStr outputs from xBestIndex are required inputs to +xFilter. However, there is no guarantee that xFilter will be called +following a successful xBestIndex. + +</p><p>The xBestIndex method is required for every virtual table implementation. + +</p><h3 id="inputs"><span>2.3.1. </span>Inputs</h3> + +<p>The main thing that the SQLite core is trying to communicate to +the virtual table is the constraints that are available to limit +the number of rows that need to be searched. The aConstraint[] array +contains one entry for each constraint. There will be exactly +nConstraint entries in that array. + +</p><p>Each constraint will usually correspond to a term in the WHERE clause +or in a USING or ON clause that is of the form + +</p><blockquote> + column OP EXPR +</blockquote> + +<p>Where "column" is a column in the virtual table, OP is an operator +like "=" or "<", and EXPR is an arbitrary expression. So, for example, +if the WHERE clause contained a term like this: + +</p><div class="codeblock"><pre>a = 5 +</pre></div> + +<p>Then one of the constraints would be on the "a" column with +operator "=" and an expression of "5". Constraints need not have a +literal representation of the WHERE clause. The query optimizer might +make transformations to the +WHERE clause in order to extract as many constraints +as it can. So, for example, if the WHERE clause contained something +like this: + +</p><div class="codeblock"><pre>x BETWEEN 10 AND 100 AND 999>y +</pre></div> + +<p>The query optimizer might translate this into three separate constraints: + +</p><div class="codeblock"><pre>x >= 10 +x <= 100 +y < 999 +</pre></div> + +<p>For each such constraint, the aConstraint[].iColumn field indicates which +column appears on the left-hand side of the constraint. +The first column of the virtual table is column 0. +The rowid of the virtual table is column -1. +The aConstraint[].op field indicates which operator is used. +The SQLITE_INDEX_CONSTRAINT_* constants map integer constants +into operator values. +Columns occur in the order they were defined by the call to +<a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> in the <a href="vtab.html#xcreate">xCreate</a> or <a href="vtab.html#xconnect">xConnect</a> method. +Hidden columns are counted when determining the column index. + +</p><p>If the <a href="vtab.html#xfindfunction">xFindFunction()</a> method for the virtual table is defined, and +if xFindFunction() sometimes returns <a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_FUNCTION</a> or +larger, then the constraints might also be of the form: + +</p><blockquote> + FUNCTION( column, EXPR) +</blockquote> + +<p>In this case the aConstraint[].op value is the same as the value +returned by <a href="vtab.html#xfindfunction">xFindFunction()</a> for FUNCTION. + +</p><p>The aConstraint[] array contains information about all constraints +that apply to the virtual table. But some of the constraints might +not be usable because of the way tables are ordered in a join. +The xBestIndex method must therefore only consider constraints +that have an aConstraint[].usable flag which is true. + +</p><p>In addition to WHERE clause constraints, the SQLite core also +tells the xBestIndex method about the ORDER BY clause. +(In an aggregate query, the SQLite core might put in GROUP BY clause +information in place of the ORDER BY clause information, but this fact +should not make any difference to the xBestIndex method.) +If all terms of the ORDER BY clause are columns in the virtual table, +then nOrderBy will be the number of terms in the ORDER BY clause +and the aOrderBy[] array will identify the column for each term +in the order by clause and whether or not that column is ASC or DESC. + +<a name="colUsed"></a> + +</p><p>In SQLite <a href="releaselog/3_10_0.html">version 3.10.0</a> (2016-01-06) and later, +the colUsed field is available +to indicate which fields of the virtual table are actually used by the +statement being prepared. If the lowest bit of colUsed is set, that +means that the first column is used. The second lowest bit corresponds +to the second column. And so forth. If the most significant bit of +colUsed is set, that means that one or more columns other than the +first 63 columns are used. If column usage information is needed by the +<a href="vtab.html#xfilter">xFilter</a> method, then the required bits must be encoded into either +the output idxNum field or idxStr content. + +</p><h4 id="like_glob_regexp_and_match_functions"><span>2.3.1.1. </span>LIKE, GLOB, REGEXP, and MATCH functions</h4> + +<p>For the LIKE, GLOB, REGEXP, and MATCH operators, the +aConstraint[].iColumn value is the virtual table column that +is the left operand of the operator. However, if these operators +are expressed as function calls instead of operators, then +the aConstraint[].iColumn value references the virtual table +column that is the second argument to that function: + +</p><blockquote> +LIKE(<i>EXPR</i>, <i>column</i>)<br> +GLOB(<i>EXPR</i>, <i>column</i>)<br> +REGEXP(<i>EXPR</i>, <i>column</i>)<br> +MATCH(<i>EXPR</i>, <i>column</i>)<br> +</blockquote> + +<p>Hence, as far as the xBestIndex() method is concerned, the following +two forms are equivalent: + +</p><blockquote> +<i>column</i> LIKE <i>EXPR</i><br> +LIKE(<i>EXPR</i>,<i>column</i>) +</blockquote> + +<p>This special behavior of looking at the second argument of a function +only occurs for the LIKE, GLOB, REGEXP, and MATCH functions. For all +other functions, the aConstraint[].iColumn value references the first +argument of the function. + +</p><p>This special feature of LIKE, GLOB, REGEXP, and MATCH does not +apply to the <a href="vtab.html#xfindfunction">xFindFunction()</a> method, however. The +<a href="vtab.html#xfindfunction">xFindFunction()</a> method always keys off of the left operand of an +LIKE, GLOB, REGEXP, or MATCH operator but off of the first argument +to function-call equivalents of those operators. + +</p><h4 id="limit_and_offset"><span>2.3.1.2. </span>LIMIT and OFFSET</h4> + +<p>When aConstraint[].op is one of SQLITE_INDEX_CONSTRAINT_LIMIT or +SQLITE_INDEX_CONSTRAINT_OFFSET, that indicates that there is a +LIMIT or OFFSET clause on the SQL query statement that is using +the virtual table. The LIMIT and OFFSET operators have no +left operand, and so when aConstraint[].op is one of +SQLITE_INDEX_CONSTRAINT_LIMIT or SQLITE_INDEX_CONSTRAINT_OFFSET +then the aConstraint[].iColumn value is meaningless and should +not be used. + +</p><h4 id="right_hand_side_values_of_constraints"><span>2.3.1.3. </span>Right-hand side values of constraints</h4> + +<p>The <a href="c3ref/vtab_rhs_value.html">sqlite3_vtab_rhs_value()</a> interface can be used to try to +access the right-hand operand of a constraint. However, the value +of a right-hand operator might not be known at the time that +the xBestIndex method is run, so the sqlite3_vtab_rhs_value() +call might not be successful. Usually the right operand of a +constraint is only available to xBestIndex if it is coded as +a literal value in the input SQL. If the right operand is +coded as an expression or a <a href="c3ref/bind_blob.html">host parameter</a>, it probably will +not be accessible to xBestIndex. Some operators, such as +<a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_ISNULL</a> and +<a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_ISNOTNULL</a> have no right-hand operand. +The sqlite3_vtab_rhs_value() interface always returns +<a href="rescode.html#notfound">SQLITE_NOTFOUND</a> for such operators. + +</p><h3 id="outputs"><span>2.3.2. </span>Outputs</h3> + +<p>Given all of the information above, the job of the xBestIndex +method it to figure out the best way to search the virtual table. + +</p><p>The xBestIndex method conveys an indexing strategy to the <a href="vtab.html#xfilter">xFilter</a> +method through the idxNum and idxStr fields. The idxNum value and +idxStr string content are arbitrary as far as the SQLite core is +concerned and can have any meaning as long as xBestIndex and xFilter +agree on what that meaning is. The SQLite core just copies the +information from xBestIndex through to the <a href="vtab.html#xfilter">xFilter</a> method, assuming +only that the char sequence referenced via idxStr is NUL terminated. + +</p><p>The idxStr value may be a string obtained from an SQLite +memory allocation function such as <a href="c3ref/mprintf.html">sqlite3_mprintf()</a>. +If this is the case, then the needToFreeIdxStr flag must be set to +true so that the SQLite core will know to call <a href="c3ref/free.html">sqlite3_free()</a> on +that string when it has finished with it, and thus avoid a memory leak. +The idxStr value may also be a static constant string, in which case +the needToFreeIdxStr boolean should remain false. + + +</p><p>The estimatedCost field should be set to the estimated number +of disk access operations required to execute this query against +the virtual table. The SQLite core will often call xBestIndex +multiple times with different constraints, obtain multiple cost +estimates, then choose the query plan that gives the lowest estimate. +The SQLite core initializes estimatedCost to a very large value +prior to invoking xBestIndex, so if xBestIndex determines that the +current combination of parameters is undesirable, it can leave the +estimatedCost field unchanged to discourage its use. + +</p><p>If the current version of SQLite is 3.8.2 or greater, the estimatedRows +field may be set to an estimate of the number of rows returned by the +proposed query plan. If this value is not explicitly set, the default +estimate of 25 rows is used. + +</p><p>If the current version of SQLite is 3.9.0 or greater, the idxFlags field +may be set to SQLITE_INDEX_SCAN_UNIQUE to indicate that the virtual table +will return only zero or one rows given the input constraints. Additional +bits of the idxFlags field might be understood in later versions of SQLite. + +</p><p>The aConstraintUsage[] array contains one element for each of +the nConstraint constraints in the inputs section of the +<a href="c3ref/index_info.html">sqlite3_index_info</a> structure. +The aConstraintUsage[] array is used by xBestIndex to tell the +core how it is using the constraints. + +</p><p>The xBestIndex method may set aConstraintUsage[].argvIndex +entries to values greater than zero. +Exactly one entry should be set to 1, another to 2, another to 3, +and so forth up to as many or as few as the xBestIndex method wants. +The EXPR of the corresponding constraints will then be passed +in as the argv[] parameters to xFilter. + +</p><p>For example, if the aConstraint[3].argvIndex is set to 1, then +when xFilter is called, the argv[0] passed to xFilter will have +the EXPR value of the aConstraint[3] constraint. + +</p><h4 id="omit_constraint_checking_in_bytecode"><span>2.3.2.1. </span>Omit constraint checking in bytecode</h4> + +<p>By default, the SQLite generates <a href="opcode.html">bytecode</a> that will double +checks all constraints on each row of the virtual table to verify +that they are satisfied. If the virtual table can guarantee +that a constraint will always be satisfied, it can try to +suppress that double-check by setting aConstraintUsage[].omit. +However, with some exceptions, this is only a hint and +there is no guarantee that the redundant check of the constraint +will be suppressed. Key points: + +</p><ul> +<li><p> +The omit flag is only honored if the argvIndex value for the +constraint is greater than 0 and less than or equal to 16. +Constraint checking is never suppressed for constraints +that do not pass their right operand into the xFilter method. +The current implementation is only able to suppress redundant +constraint checking for the first 16 values passed to xFilter, +though that limitation might be increased in future releases. + +</p></li><li><p> +The omit flag is always honored for <a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_OFFSET</a> +constraints as long as argvIndex is greater than 0. Setting the +omit flag on an SQLITE_INDEX_CONSTRAINT_OFFSET constraint indicates +to SQLite that the virtual table will itself suppress the first N +rows of output, where N is the right operand of the OFFSET operator. +If the virtual table implementation sets omit on an +SQLITE_INDEX_CONSTRAINT_OFFSET constraint but then fails to suppress +the first N rows of output, an incorrect answer will result from +the overall query. +</p></li></ul> + +<a name="obc"></a> + +<h4 id="order_by_and_orderbyconsumed"><span>2.3.2.2. </span>ORDER BY and orderByConsumed</h4> + +<p>If the virtual table will output rows in the order specified by +the ORDER BY clause, then the orderByConsumed flag may be set to +true. If the output is not automatically in the correct order +then orderByConsumed must be left in its default false setting. +This will indicate to the SQLite core that it will need to do a +separate sorting pass over the data after it comes out of the virtual table. +Setting orderByConsumed is an optimization. A query will always +get the correct answer if orderByConsumed is left at its default +value (0). Unnecessary sort operations might be avoided resulting +in a faster query if orderByConsumed is set, but setting +orderByConsumed incorrectly can result in an incorrect answer. +It is suggested that new virtual table implementations leave +the orderByConsumed value unset initially, and then after everything +else is known to be working correctly, go back and attempt to +optimize by setting orderByConsumed where appropriate. + +</p><p>Sometimes the orderByConsumed flag can be safely set even if +the outputs from the virtual table are not strictly in the order +specified by nOrderBy and aOrderBy. If the +<a href="c3ref/vtab_distinct.html">sqlite3_vtab_distinct()</a> interface returns 1 or 2, that indicates +that the ordering can be relaxed. See the documentation on +<a href="c3ref/vtab_distinct.html">sqlite3_vtab_distinct()</a> for further information. + + +</p><h3 id="return_value"><span>2.3.3. </span>Return Value</h3> + +<p>The xBestIndex method should return SQLITE_OK on success. If any +kind of fatal error occurs, an appropriate error code (ex: <a href="rescode.html#nomem">SQLITE_NOMEM</a>) +should be returned instead. + +</p><p>If xBestIndex returns <a href="rescode.html#constraint">SQLITE_CONSTRAINT</a>, that does not indicate an +error. Rather, SQLITE_CONSTRAINT indicates that the particular combination +of input parameters specified is insufficient for the virtual table +to do its job. +This is logically the same as setting the estimatedCost to infinity. +If every call to xBestIndex for a particular query plan returns +SQLITE_CONSTRAINT, that means there is no way for the virtual table +to be safely used, and the <a href="c3ref/prepare.html">sqlite3_prepare()</a> call will fail with +a "no query solution" error. + +</p><h3 id="enforcing_required_parameters_on_table_valued_functions"><span>2.3.4. </span>Enforcing Required Parameters On Table-Valued Functions</h3> + +<p>The SQLITE_CONSTRAINT return from xBestIndex +is useful for <a href="vtab.html#tabfunc2">table-valued functions</a> that +have required parameters. If the aConstraint[].usable field is false +for one of the required parameter, then the xBestIndex method should +return SQLITE_CONSTRAINT. If a required field does not appear in +the aConstraint[] array at all, that means that the corresponding +parameter is omitted from the input SQL. In that case, xBestIndex +should set an error message in pVTab->zErrMsg and return +SQLITE_ERROR. To summarize: + +</p><ol> +<li><p> +The aConstraint[].usable value for a required parameter is +false <big>→</big> return SQLITE_CONSTRAINT. +</p></li><li><p> +A required parameter does not appears anywhere in +the aConstraint[] array <big>→</big> +Set an error message in pVTab->zErrMsg and return +SQLITE_ERROR +</p></li></ol> + +<p>The following example will better illustrate the use of SQLITE_CONSTRAINT +as a return value from xBestIndex: + +</p><div class="codeblock"><pre>SELECT * FROM realtab, tablevaluedfunc(realtab.x); +</pre></div> + +<p>Assuming that the first hidden column of "tablevaluedfunc" is "param1", +the query above is semantically equivalent to this: + +</p><div class="codeblock"><pre>SELECT * FROM realtab, tablevaluedfunc + WHERE tablevaluedfunc.param1 = realtab.x; +</pre></div> + +<p>The query planner must decide between many possible implementations +of this query, but two plans in particular are of note: + +</p><ol> +<li><p>Scan all +rows of realtab and for each row, find rows in tablevaluedfunc where +param1 is equal to realtab.x + +</p></li><li><p>Scan all rows of tablevalued func and for each row find rows +in realtab where x is equal to tablevaluedfunc.param1. +</p></li></ol> + +<p>The xBestIndex method will be invoked once for each of the potential +plans above. For plan 1, the aConstraint[].usable flag for the +SQLITE_CONSTRAINT_EQ constraint on the param1 column will be true because +the right-hand side value for the "param1 = ?" constraint will be known, +since it is determined by the outer realtab loop. +But for plan 2, the aConstraint[].usable flag for "param1 = ?" will be false +because the right-hand side value is determined by an inner loop and is thus +an unknown quantity. Because param1 is a required input to the table-valued +functions, the xBestIndex method should return SQLITE_CONSTRAINT when presented +with plan 2, indicating that a required input is missing. This forces the +query planner to select plan 1. + +<a name="xdisconnect"></a> + +</p><h2 id="the_xdisconnect_method"><span>2.4. </span>The xDisconnect Method</h2> + +<div class="codeblock"><pre>int (*xDisconnect)(sqlite3_vtab *pVTab); +</pre></div> + +<p>This method releases a connection to a virtual table. +Only the <a href="c3ref/vtab.html">sqlite3_vtab</a> object is destroyed. +The virtual table is not destroyed and any backing store +associated with the virtual table persists. + +This method undoes the work of <a href="vtab.html#xconnect">xConnect</a>. + +</p><p>This method is a destructor for a connection to the virtual table. +Contrast this method with <a href="vtab.html#sqlite3_module.xDestroy">xDestroy</a>. The xDestroy is a destructor +for the entire virtual table. + +</p><p>The xDisconnect method is required for every virtual table implementation, +though it is acceptable for the xDisconnect and <a href="vtab.html#sqlite3_module.xDestroy">xDestroy</a> methods to be +the same function if that makes sense for the particular virtual table. + +<a name="sqlite3_module.xDestroy"></a> + +</p><h2 id="the_xdestroy_method"><span>2.5. </span>The xDestroy Method</h2> + +<div class="codeblock"><pre>int (*xDestroy)(sqlite3_vtab *pVTab); +</pre></div> + +<p>This method releases a connection to a virtual table, just like +the <a href="vtab.html#xdisconnect">xDisconnect</a> method, and it also destroys the underlying +table implementation. This method undoes the work of <a href="vtab.html#xcreate">xCreate</a>. + +</p><p>The <a href="vtab.html#xdisconnect">xDisconnect</a> method is called whenever a database connection +that uses a virtual table is closed. The xDestroy method is only +called when a <a href="lang_droptable.html">DROP TABLE</a> statement is executed against the virtual table. + +</p><p>The xDestroy method is required for every virtual table implementation, +though it is acceptable for the <a href="vtab.html#xdisconnect">xDisconnect</a> and xDestroy methods to be +the same function if that makes sense for the particular virtual table. + +<a name="xopen"></a> + +</p><h2 id="the_xopen_method"><span>2.6. </span>The xOpen Method</h2> + +<div class="codeblock"><pre>int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); +</pre></div> + +<p>The xOpen method creates a new cursor used for accessing (read and/or +writing) a virtual table. A successful invocation of this method +will allocate the memory for the <a href="c3ref/vtab_cursor.html">sqlite3_vtab_cursor</a> (or a subclass), +initialize the new object, and make *ppCursor point to the new object. +The successful call then returns <a href="rescode.html#ok">SQLITE_OK</a>. + +</p><p>For every successful call to this method, the SQLite core will +later invoke the <a href="vtab.html#xclose">xClose</a> method to destroy +the allocated cursor. + +</p><p>The xOpen method need not initialize the pVtab field of the +<a href="c3ref/vtab_cursor.html">sqlite3_vtab_cursor</a> structure. The SQLite core will take care +of that chore automatically. + +</p><p>A virtual table implementation must be able to support an arbitrary +number of simultaneously open cursors. + +</p><p>When initially opened, the cursor is in an undefined state. +The SQLite core will invoke the <a href="vtab.html#xfilter">xFilter</a> method +on the cursor prior to any attempt to position or read from the cursor. + +</p><p>The xOpen method is required for every virtual table implementation. + +<a name="xclose"></a> + +</p><h2 id="the_xclose_method"><span>2.7. </span>The xClose Method</h2> + +<div class="codeblock"><pre>int (*xClose)(sqlite3_vtab_cursor*); +</pre></div> + +<p>The xClose method closes a cursor previously opened by +<a href="vtab.html#xopen">xOpen</a>. +The SQLite core will always call xClose once for each cursor opened +using xOpen. + +</p><p>This method must release all resources allocated by the +corresponding xOpen call. The routine will not be called again even if it +returns an error. The SQLite core will not use the +<a href="c3ref/vtab_cursor.html">sqlite3_vtab_cursor</a> again after it has been closed. + +</p><p>The xClose method is required for every virtual table implementation. + +<a name="xeof"></a> + +</p><h2 id="the_xeof_method"><span>2.8. </span>The xEof Method</h2> + +<div class="codeblock"><pre>int (*xEof)(sqlite3_vtab_cursor*); +</pre></div> + +<p>The xEof method must return false (zero) if the specified cursor +currently points to a valid row of data, or true (non-zero) otherwise. +This method is called by the SQL engine immediately after each +<a href="vtab.html#xfilter">xFilter</a> and <a href="vtab.html#xnext">xNext</a> invocation. + +</p><p>The xEof method is required for every virtual table implementation. + +<a name="xfilter"></a> + +</p><h2 id="the_xfilter_method"><span>2.9. </span>The xFilter Method</h2> + +<div class="codeblock"><pre>int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); +</pre></div> + +<p>This method begins a search of a virtual table. +The first argument is a cursor opened by <a href="vtab.html#xopen">xOpen</a>. +The next two arguments define a particular search index previously +chosen by <a href="vtab.html#xbestindex">xBestIndex</a>. The specific meanings of idxNum and idxStr +are unimportant as long as xFilter and xBestIndex agree on what +that meaning is. + +</p><p>The xBestIndex function may have requested the values of +certain expressions using the aConstraintUsage[].argvIndex values +of the <a href="c3ref/index_info.html">sqlite3_index_info</a> structure. +Those values are passed to xFilter using the argc and argv parameters. + +</p><p>If the virtual table contains one or more rows that match the +search criteria, then the cursor must be left point at the first row. +Subsequent calls to <a href="vtab.html#xeof">xEof</a> must return false (zero). +If there are no rows match, then the cursor must be left in a state +that will cause the <a href="vtab.html#xeof">xEof</a> to return true (non-zero). +The SQLite engine will use +the <a href="vtab.html#xcolumn">xColumn</a> and <a href="vtab.html#xrowid">xRowid</a> methods to access that row content. +The <a href="vtab.html#xnext">xNext</a> method will be used to advance to the next row. + +</p><p>This method must return <a href="rescode.html#ok">SQLITE_OK</a> if successful, or an sqlite +<a href="rescode.html">error code</a> if an error occurs. + +</p><p>The xFilter method is required for every virtual table implementation. + +<a name="xnext"></a> + +</p><h2 id="the_xnext_method"><span>2.10. </span>The xNext Method</h2> + +<div class="codeblock"><pre>int (*xNext)(sqlite3_vtab_cursor*); +</pre></div> + +<p>The xNext method advances a <a href="c3ref/vtab_cursor.html">virtual table cursor</a> +to the next row of a result set initiated by <a href="vtab.html#xfilter">xFilter</a>. +If the cursor is already pointing at the last row when this +routine is called, then the cursor no longer points to valid +data and a subsequent call to the <a href="vtab.html#xeof">xEof</a> method must return true (non-zero). +If the cursor is successfully advanced to another row of content, then +subsequent calls to <a href="vtab.html#xeof">xEof</a> must return false (zero). + +</p><p>This method must return <a href="rescode.html#ok">SQLITE_OK</a> if successful, or an sqlite +<a href="rescode.html">error code</a> if an error occurs. + +</p><p>The xNext method is required for every virtual table implementation. + +<a name="xcolumn"></a> + +</p><h2 id="the_xcolumn_method"><span>2.11. </span>The xColumn Method</h2> + +<div class="codeblock"><pre>int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int N); +</pre></div> + +<p>The SQLite core invokes this method in order to find the value for +the N-th column of the current row. N is zero-based so the first column +is numbered 0. +The xColumn method may return its result back to SQLite using one of the +following interface: + +</p><p> +</p><ul> +<li> <a href="c3ref/result_blob.html">sqlite3_result_blob()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_double()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_int()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_int64()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_null()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_text()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_text16()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_text16le()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_text16be()</a> +</li><li> <a href="c3ref/result_blob.html">sqlite3_result_zeroblob()</a> +</li></ul> + + +<p>If the xColumn method implementation calls none of the functions above, +then the value of the column defaults to an SQL NULL. + +</p><p>To raise an error, the xColumn method should use one of the result_text() +methods to set the error message text, then return an appropriate +<a href="rescode.html">error code</a>. The xColumn method must return <a href="rescode.html#ok">SQLITE_OK</a> on success. + +</p><p>The xColumn method is required for every virtual table implementation. + +<a name="xrowid"></a> + +</p><h2 id="the_xrowid_method"><span>2.12. </span>The xRowid Method</h2> + +<div class="codeblock"><pre>int (*xRowid)(sqlite3_vtab_cursor *pCur, sqlite_int64 *pRowid); +</pre></div> + +<p>A successful invocation of this method will cause *pRowid to be +filled with the <a href="lang_createtable.html#rowid">rowid</a> of row that the +<a href="c3ref/vtab_cursor.html">virtual table cursor</a> pCur is currently pointing at. +This method returns <a href="rescode.html#ok">SQLITE_OK</a> on success. +It returns an appropriate <a href="rescode.html">error code</a> on failure.</p> + +<p>The xRowid method is required for every virtual table implementation. + +<a name="xupdate"></a> + +</p><h2 id="the_xupdate_method"><span>2.13. </span>The xUpdate Method</h2> + +<div class="codeblock"><pre>int (*xUpdate)( + sqlite3_vtab *pVTab, + int argc, + sqlite3_value **argv, + sqlite_int64 *pRowid +); +</pre></div> + +<p>All changes to a virtual table are made using the xUpdate method. +This one method can be used to insert, delete, or update. + +</p><p>The argc parameter specifies the number of entries in the argv array. +The value of argc will be 1 for a pure delete operation or N+2 for an insert +or replace or update where N is the number of columns in the table. +In the previous sentence, N includes any hidden columns. + +</p><p>Every argv entry will have a non-NULL value in C but may contain the +SQL value NULL. In other words, it is always true that +<tt>argv[i]!=0</tt> for <b>i</b> between 0 and <tt>argc-1</tt>. +However, it might be the case that +<tt>sqlite3_value_type(argv[i])==SQLITE_NULL</tt>. + +</p><p>The argv[0] parameter is the <a href="lang_createtable.html#rowid">rowid</a> of a row in the virtual table +to be deleted. If argv[0] is an SQL NULL, then no deletion occurs. + +</p><p>The argv[1] parameter is the rowid of a new row to be inserted +into the virtual table. If argv[1] is an SQL NULL, then the implementation +must choose a rowid for the newly inserted row. Subsequent argv[] +entries contain values of the columns of the virtual table, in the +order that the columns were declared. The number of columns will +match the table declaration that the <a href="vtab.html#xconnect">xConnect</a> or <a href="vtab.html#xcreate">xCreate</a> method made +using the <a href="c3ref/declare_vtab.html">sqlite3_declare_vtab()</a> call. All hidden columns are included. + +</p><p>When doing an insert without a rowid (argc>1, argv[1] is an SQL NULL), +on a virtual table that uses ROWID (but not on a <a href="vtab.html#worid">WITHOUT ROWID virtual table</a>), +the implementation must set *pRowid to the rowid of the newly inserted row; +this will become the value returned by the <a href="c3ref/last_insert_rowid.html">sqlite3_last_insert_rowid()</a> +function. Setting this value in all the other cases is a harmless no-op; +the SQLite engine ignores the *pRowid return value if argc==1 or +argv[1] is not an SQL NULL. + +</p><p>Each call to xUpdate will fall into one of cases shown below. +Not that references to <b>argv[i]</b> mean the SQL value +held within the argv[i] object, not the argv[i] +object itself. + +</p><blockquote> +<dl> +<dt><b>argc = 1 <br> argv[0] ≠ NULL</b> +</dt><dd><p> +DELETE: The single row with rowid or PRIMARY KEY equal to argv[0] is deleted. +No insert occurs. + +</p></dd><dt><b>argc > 1 <br> argv[0] = NULL</b> +</dt><dd><p> +INSERT: A new row is inserted with column values taken from +argv[2] and following. In a rowid virtual table, if argv[1] is an SQL NULL, +then a new unique rowid is generated automatically. The argv[1] will be NULL +for a <a href="vtab.html#worid">WITHOUT ROWID virtual table</a>, in which case the implementation should +take the PRIMARY KEY value from the appropriate column in argv[2] and following. + +</p></dd><dt><b>argc > 1 <br> argv[0] ≠ NULL <br> argv[0] = argv[1]</b> +</dt><dd><p> +UPDATE: +The row with rowid or PRIMARY KEY argv[0] is updated with new values +in argv[2] and following parameters. + +</p></dd><dt><b>argc > 1 <br> argv[0] ≠ NULL <br> argv[0] ≠ argv[1]</b> +</dt><dd><p> +UPDATE with rowid or PRIMARY KEY change: +The row with rowid or PRIMARY KEY argv[0] is updated with +the rowid or PRIMARY KEY in argv[1] +and new values in argv[2] and following parameters. This will occur +when an SQL statement updates a rowid, as in the statement: +</p><blockquote> + <a href="lang_update.html">UPDATE</a> table SET rowid=rowid+1 WHERE ...; +</blockquote> +</dd></dl> +</blockquote> + +<p>The xUpdate method must return <a href="rescode.html#ok">SQLITE_OK</a> if and only if it is +successful. If a failure occurs, the xUpdate must return an appropriate +<a href="rescode.html">error code</a>. On a failure, the pVTab->zErrMsg element may optionally +be replaced with error message text stored in memory allocated from SQLite +using functions such as <a href="c3ref/mprintf.html">sqlite3_mprintf()</a> or <a href="c3ref/free.html">sqlite3_malloc()</a>. + +</p><p>If the xUpdate method violates some constraint of the virtual table +(including, but not limited to, attempting to store a value of the wrong +datatype, attempting to store a value that is too +large or too small, or attempting to change a read-only value) then the +xUpdate must fail with an appropriate <a href="rescode.html">error code</a>. + +</p><p>If the xUpdate method is performing an UPDATE, then +<a href="c3ref/value_blob.html">sqlite3_value_nochange(X)</a> can be used to discover which columns +of the virtual table were actually modified by the UPDATE +statement. The <a href="c3ref/value_blob.html">sqlite3_value_nochange(X)</a> interface returns +true for columns that do not change. +On every UPDATE, SQLite will first invoke +<a href="vtab.html#xcolumn">xColumn</a> separately for each unchanging column in the table to +obtain the value for that column. The <a href="vtab.html#xcolumn">xColumn</a> method can +check to see if the column is unchanged at the SQL level +by invoking <a href="c3ref/vtab_nochange.html">sqlite3_vtab_nochange()</a>. If <a href="vtab.html#xcolumn">xColumn</a> sees that +the column is not being modified, it should return without setting +a result using one of the <a href="c3ref/result_blob.html">sqlite3_result_xxxxx()</a> +interfaces. Only in that case <a href="c3ref/value_blob.html">sqlite3_value_nochange()</a> will be +true within the xUpdate method. If <a href="vtab.html#xcolumn">xColumn</a> does +invoke one or more <a href="c3ref/result_blob.html">sqlite3_result_xxxxx()</a> +interfaces, then SQLite understands that as a change in the value +of the column and the <a href="c3ref/value_blob.html">sqlite3_value_nochange()</a> call for that +column within xUpdate will return false. + +</p><p>There might be one or more <a href="c3ref/vtab_cursor.html">sqlite3_vtab_cursor</a> objects open and in use +on the virtual table instance and perhaps even on the row of the virtual +table when the xUpdate method is invoked. The implementation of +xUpdate must be prepared for attempts to delete or modify rows of the table +out from other existing cursors. If the virtual table cannot accommodate +such changes, the xUpdate method must return an <a href="rescode.html">error code</a>. + +</p><p>The xUpdate method is optional. +If the xUpdate pointer in the <a href="c3ref/module.html">sqlite3_module</a> for a virtual table +is a NULL pointer, then the virtual table is read-only. + + +<a name="xfindfunction"></a> + +</p><h2 id="the_xfindfunction_method"><span>2.14. </span>The xFindFunction Method</h2> + +<div class="codeblock"><pre>int (*xFindFunction)( + sqlite3_vtab *pVtab, + int nArg, + const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), + void **ppArg +); +</pre></div> + +<p>This method is called during <a href="c3ref/prepare.html">sqlite3_prepare()</a> to give the virtual +table implementation an opportunity to overload functions. +This method may be set to NULL in which case no overloading occurs. + +</p><p>When a function uses a column from a virtual table as its first +argument, this method is called to see if the virtual table would +like to overload the function. The first three parameters are inputs: +the virtual table, the number of arguments to the function, and the +name of the function. If no overloading is desired, this method +returns 0. To overload the function, this method writes the new +function implementation into *pxFunc and writes user data into *ppArg +and returns either 1 or a number between +<a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_FUNCTION</a> and 255. + +</p><p>Historically, the return value from xFindFunction() was either zero +or one. Zero means that the function is not overloaded and one means that +it is overload. The ability to return values of +<a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_FUNCTION</a> or greater was added in +version 3.25.0 (2018-09-15). If xFindFunction returns +<a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_FUNCTION</a> or greater, than means that the function +takes two arguments and the function +can be used as a boolean in the WHERE clause of a query and that +the virtual table is able to exploit that function to speed up the query +result. When xFindFunction returns <a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_FUNCTION</a> or +larger, the value returned becomes the <a href="c3ref/index_info.html">sqlite3_index_info</a>.aConstraint.op +value for one of the constraints passed into <a href="vtab.html#xbestindex">xBestIndex()</a>. The first +argument to the function is the column identified by +aConstraint[].iColumn field of the constraint and the second argument to the +function is the value that will be passed into <a href="vtab.html#xfilter">xFilter()</a> (if the +aConstraintUsage[].argvIndex value is set) or the value returned from +<a href="c3ref/vtab_rhs_value.html">sqlite3_vtab_rhs_value()</a>. + +</p><p>The <a href="geopoly.html">Geopoly module</a> is an example of a virtual table that makes use +of <a href="c3ref/c_index_constraint_eq.html">SQLITE_INDEX_CONSTRAINT_FUNCTION</a> to improve performance. +The xFindFunction() method for Geopoly returns +SQLITE_INDEX_CONSTRAINT_FUNCTION for the <a href="geopoly.html#goverlap">geopoly_overlap()</a> SQL function +and it returns +SQLITE_INDEX_CONSTRAINT_FUNCTION+1 for the <a href="geopoly.html#gwithin">geopoly_within()</a> SQL function. +This permits search optimizations for queries such as: + +</p><div class="codeblock"><pre>SELECT * FROM geopolytab WHERE geopoly_overlap(_shape, $query_polygon); +SELECT * FROM geopolytab WHERE geopoly_within(_shape, $query_polygon); +</pre></div> + +<p>Note that infix functions (<a href="lang_expr.html#like">LIKE</a>, <a href="lang_expr.html#glob">GLOB</a>, <a href="lang_expr.html#regexp">REGEXP</a>, and <a href="lang_expr.html#match">MATCH</a>) reverse +the order of their arguments. So "like(A,B)" would normally work the same +as "B like A". +However, xFindFunction() always looks a the left-most argument, not +the first logical argument. +Hence, for the form "B like A", SQLite looks at the +left operand "B" and if that operand is a virtual table column +it invokes the xFindFunction() method on that virtual table. +But if the form "like(A,B)" is used instead, then SQLite checks +the A term to see if it is column of a virtual table and if so +it invokes the xFindFunction() method for the virtual table of +column A. + +</p><p>The function pointer returned by this routine must be valid for +the lifetime of the <a href="c3ref/vtab.html">sqlite3_vtab</a> object given in the first parameter. + +<a name="xBegin"></a> + +</p><h2 id="the_xbegin_method"><span>2.15. </span>The xBegin Method</h2> + +<div class="codeblock"><pre>int (*xBegin)(sqlite3_vtab *pVTab); +</pre></div> + +<p>This method begins a transaction on a virtual table. +This is method is optional. The xBegin pointer of <a href="c3ref/module.html">sqlite3_module</a> +may be NULL. + +</p><p>This method is always followed by one call to either the +<a href="vtab.html#xcommit">xCommit</a> or <a href="vtab.html#xrollback">xRollback</a> method. Virtual table transactions do +not nest, so the xBegin method will not be invoked more than once +on a single virtual table +without an intervening call to either <a href="vtab.html#xcommit">xCommit</a> or <a href="vtab.html#xrollback">xRollback</a>. +Multiple calls to other methods can and likely will occur in between +the xBegin and the corresponding <a href="vtab.html#xcommit">xCommit</a> or <a href="vtab.html#xrollback">xRollback</a>. + +<a name="xsync"></a> + +</p><h2 id="the_xsync_method"><span>2.16. </span>The xSync Method</h2> + +<div class="codeblock"><pre>int (*xSync)(sqlite3_vtab *pVTab); +</pre></div> + + +<p>This method signals the start of a two-phase commit on a virtual +table. +This is method is optional. The xSync pointer of <a href="c3ref/module.html">sqlite3_module</a> +may be NULL. + +</p><p>This method is only invoked after call to the <a href="vtab.html#xBegin">xBegin</a> method and +prior to an <a href="vtab.html#xcommit">xCommit</a> or <a href="vtab.html#xrollback">xRollback</a>. In order to implement two-phase +commit, the xSync method on all virtual tables is invoked prior to +invoking the <a href="vtab.html#xcommit">xCommit</a> method on any virtual table. If any of the +xSync methods fail, the entire transaction is rolled back. + +<a name="xcommit"></a> + +</p><h2 id="the_xcommit_method"><span>2.17. </span>The xCommit Method</h2> + +<div class="codeblock"><pre>int (*xCommit)(sqlite3_vtab *pVTab); +</pre></div> + +<p>This method causes a virtual table transaction to commit. +This is method is optional. The xCommit pointer of <a href="c3ref/module.html">sqlite3_module</a> +may be NULL. + +</p><p>A call to this method always follows a prior call to <a href="vtab.html#xBegin">xBegin</a> and +<a href="vtab.html#xsync">xSync</a>. + + +<a name="xrollback"></a> + +</p><h2 id="the_xrollback_method"><span>2.18. </span>The xRollback Method</h2> + +<div class="codeblock"><pre>int (*xRollback)(sqlite3_vtab *pVTab); +</pre></div> + +<p>This method causes a virtual table transaction to rollback. +This is method is optional. The xRollback pointer of <a href="c3ref/module.html">sqlite3_module</a> +may be NULL. + +</p><p>A call to this method always follows a prior call to <a href="vtab.html#xBegin">xBegin</a>. + + +<a name="xrename"></a> + +</p><h2 id="the_xrename_method"><span>2.19. </span>The xRename Method</h2> + +<div class="codeblock"><pre>int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); +</pre></div> + +<p>This method provides notification that the virtual table implementation +that the virtual table will be given a new name. +If this method returns <a href="rescode.html#ok">SQLITE_OK</a> then SQLite renames the table. +If this method returns an <a href="rescode.html">error code</a> then the renaming is prevented. + +</p><p>The xRename method is optional. If omitted, then the virtual +table may not be renamed using the ALTER TABLE RENAME command. + +</p><p>The <a href="pragma.html#pragma_legacy_alter_table">PRAGMA legacy_alter_table</a> setting is enabled prior to invoking this +method, and the value for legacy_alter_table is restored after this +method finishes. This is necessary for the correct operation of virtual +tables that make use of <a href="vtab.html#xshadowname">shadow tables</a> where the shadow tables must be +renamed to match the new virtual table name. If the legacy_alter_format is +off, then the xConnect method will be invoked for the virtual table every +time the xRename method tries to change the name of the shadow table. + +<a name="xsavepoint"></a> + +</p><h2 id="the_xsavepoint_xrelease_and_xrollbackto_methods"><span>2.20. </span>The xSavepoint, xRelease, and xRollbackTo Methods</h2> + +<div class="codeblock"><pre>int (*xSavepoint)(sqlite3_vtab *pVtab, int); +int (*xRelease)(sqlite3_vtab *pVtab, int); +int (*xRollbackTo)(sqlite3_vtab *pVtab, int); +</pre></div> + +<p> +These methods provide the virtual table implementation an opportunity to +implement nested transactions. They are always optional and will only be +called in SQLite <a href="releaselog/3_7_7.html">version 3.7.7</a> (2011-06-23) and later. +</p> + +<p> +When xSavepoint(X,N) is invoked, that is a signal to the virtual table X +that it should save its current state as savepoint N. +A subsequent call +to xRollbackTo(X,R) means that the state of the virtual table should return +to what it was when xSavepoint(X,R) was last called. +The call +to xRollbackTo(X,R) will invalidate all savepoints with N>R; none of the +invalided savepoints will be rolled back or released without first +being reinitialized by a call to xSavepoint(). +A call to xRelease(X,M) invalidates all savepoints where N>=M. +</p> + +<p> +None of the xSavepoint(), xRelease(), or xRollbackTo() methods will ever +be called except in between calls to xBegin() and +either xCommit() or xRollback(). +</p> + +<a name="xshadowname"></a> + +<h2 id="the_xshadowname_method"><span>2.21. </span>The xShadowName Method</h2> + +<p>Some virtual table implementations (ex: <a href="fts3.html">FTS3</a>, <a href="fts5.html">FTS5</a>, and <a href="rtree.html">RTREE</a>) make +use of real (non-virtual) database tables to store content. For example, +when content is inserted into the FTS3 virtual table, the data is ultimately +stored in real tables named "%_content", "%_segdir", "%_segments", "%_stat", +and "%_docsize" where "%" is the name of the original virtual table. This +auxiliary real tables that store content for a virtual table are called +"shadow tables". See +(<a href="fts3.html#*shadowtab">1</a>), +(<a href="fts5.html#fts5shadowtables">2</a>), and +(<a href="rtree.html#xshadow">3</a>) for additional information. + +</p><p>The xShadowName method exists to allow SQLite to determine whether a +certain real table is in fact a shadow table for a virtual table. + +</p><p>SQLite understands a real table to be a shadow table if all of +the following are true: +</p><p> +</p><ul> +<li> The name of the table contains one or more "_" characters. +</li><li> The part of the name prior to the last "_" exactly matches + the name of a virtual table that was created using <a href="lang_createvtab.html">CREATE VIRTUAL TABLE</a>. + (Shadow tables are not recognized for <a href="vtab.html#epovtab">eponymous virtual tables</a> + and <a href="vtab.html#tabfunc2">table-valued functions</a>.) +</li><li> The virtual table contains an xShadowName method. +</li><li> The xShadowName method returns true when its input is the part + of the table name past the last "_" character. +</li></ul> + +<p> +If SQLite recognizes a table as a shadow table, and if the +<a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive">SQLITE_DBCONFIG_DEFENSIVE</a> flag is set, then the shadow table is read-only +for ordinary SQL statements. The shadow table can still be written, but +only by SQL that is invoked from within one of the methods of +some virtual table implementation. + +</p><p> +The whole point of the xShadowName method is to protect the content of +shadow tables from being corrupted by hostile SQL. Every virtual table +implementation that uses shadow tables should be able to detect and cope +with corrupted shadow table content. However, bugs in particular virtual +table implementation might allow a deliberately corrupted shadow table to +cause a crash or other malfunction. The xShadowName mechanism seeks to +avoid zero-day exploits by preventing ordinary SQL statements from +deliberately corrupting shadow tables. + +</p><p> +Shadow tables are read/write by default. +Shadow tables only become read-only when the <a href="c3ref/c_dbconfig_defensive.html#sqlitedbconfigdefensive">SQLITE_DBCONFIG_DEFENSIVE</a> +flag is set using <a href="c3ref/db_config.html">sqlite3_db_config()</a>. +Shadow tables need to be read/write by default in order to maintain +backwards compatibility. +For example, the SQL text generated by the <a href="cli.html#dump">.dump</a> command of the <a href="cli.html">CLI</a> +writes directly into shadow tables. +</p><p align="center"><small><i>This page last modified on <a href="https://sqlite.org/docsrc/honeypot" id="mtimelink" data-href="https://sqlite.org/docsrc/finfo/pages/vtab.in?m=6780b9cf467a646d9">2022-12-05 12:38:46</a> UTC </small></i></p> + |